create.class.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <?php
  2. require_once dirname(__FILE__).'/resource.class.php';
  3. /**
  4. * Loads the create resource page
  5. *
  6. * @package modx
  7. * @subpackage manager.controllers
  8. */
  9. class ResourceCreateManagerController extends ResourceManagerController {
  10. /**
  11. * Check for any permissions or requirements to load page
  12. * @return bool
  13. */
  14. public function checkPermissions() {
  15. return $this->modx->hasPermission('new_document');
  16. }
  17. /**
  18. * Register custom CSS/JS for the page
  19. * @return void
  20. */
  21. public function loadCustomCssJs() {
  22. $mgrUrl = $this->modx->getOption('manager_url',null,MODX_MANAGER_URL);
  23. $this->addJavascript($mgrUrl.'assets/modext/widgets/element/modx.panel.tv.renders.js');
  24. $this->addJavascript($mgrUrl.'assets/modext/widgets/resource/modx.grid.resource.security.local.js');
  25. $this->addJavascript($mgrUrl.'assets/modext/widgets/resource/modx.panel.resource.tv.js');
  26. $this->addJavascript($mgrUrl.'assets/modext/widgets/resource/modx.panel.resource.js');
  27. $this->addJavascript($mgrUrl.'assets/modext/sections/resource/create.js');
  28. $this->addHtml('
  29. <script type="text/javascript">
  30. // <![CDATA[
  31. MODx.config.publish_document = "'.$this->canPublish.'";
  32. MODx.onDocFormRender = "'.$this->onDocFormRender.'";
  33. MODx.ctx = "'.$this->ctx.'";
  34. Ext.onReady(function() {
  35. MODx.load({
  36. xtype: "modx-page-resource-create"
  37. ,record: '.$this->modx->toJSON($this->resourceArray).'
  38. ,publish_document: "'.$this->canPublish.'"
  39. ,canSave: "'.($this->modx->hasPermission('save_document') ? 1 : 0).'"
  40. ,show_tvs: '.(!empty($this->tvCounts) ? 1 : 0).'
  41. ,mode: "create"
  42. });
  43. });
  44. // ]]>
  45. </script>');
  46. /* load RTE */
  47. $this->loadRichTextEditor();
  48. }
  49. /**
  50. * Custom logic code here for setting placeholders, etc
  51. * @param array $scriptProperties
  52. * @return mixed
  53. */
  54. public function process(array $scriptProperties = array()) {
  55. $placeholders = array();
  56. $reloadData = $this->getReloadData();
  57. /* handle template inheritance */
  58. if (!empty($this->scriptProperties['parent'])) {
  59. $this->parent = $this->modx->getObject('modResource',$this->scriptProperties['parent']);
  60. if (!$this->parent->checkPolicy('add_children')) return $this->failure($this->modx->lexicon('resource_add_children_access_denied'));
  61. } else {
  62. $this->parent = $this->modx->newObject('modResource');
  63. $this->parent->set('id',0);
  64. $this->parent->set('template',$this->modx->getOption('default_template',null,1));
  65. }
  66. $placeholders['parent'] = $this->parent;
  67. $this->setContext();
  68. if (!$this->context) { return $this->failure($this->modx->lexicon('context_err_nf')); }
  69. /* handle custom resource types */
  70. $this->resource = $this->modx->newObject($this->resourceClass);
  71. $this->resource->set('id',0);
  72. $this->resource->set('context_key',$this->context->get('key'));
  73. $placeholders['resource'] = $this->resource;
  74. $this->resourceArray = array();
  75. $placeholders['parentname'] = $this->setParent();
  76. $this->fireOnRenderEvent();
  77. /* check permissions */
  78. $this->setPermissions();
  79. /* initialize FC rules */
  80. $overridden = array();
  81. /* set default template */
  82. if (empty($reloadData)) {
  83. $defaultTemplate = $this->getDefaultTemplate();
  84. $this->resourceArray = array_merge($this->resourceArray,array(
  85. 'template' => $defaultTemplate,
  86. 'content_type' => $this->context->getOption('default_content_type',1,$this->modx->_userConfig),
  87. 'class_key' => $this->resourceClass,
  88. 'context_key' => $this->ctx,
  89. 'parent' => $this->parent->get('id'),
  90. 'richtext' => $this->context->getOption('richtext_default', true, $this->modx->_userConfig),
  91. 'hidemenu' => $this->context->getOption('hidemenu_default', 0, $this->modx->_userConfig),
  92. 'published' => $this->context->getOption('publish_default', 0, $this->modx->_userConfig),
  93. 'searchable' => $this->context->getOption('search_default', 1, $this->modx->_userConfig),
  94. 'cacheable' => $this->context->getOption('cache_default', 1, $this->modx->_userConfig),
  95. 'syncsite' => $this->context->getOption('syncsite_default', 1, $this->modx->_userConfig),
  96. ));
  97. // Allow certain fields to be prefilled from the OnDocFormRender plugin event
  98. $newValuesArr = array();
  99. $allowedFields = array('pagetitle','longtitle','description','introtext','content','link_attributes','alias','menutitle');
  100. foreach ($allowedFields as $field) {
  101. $value = $this->resource->get($field);
  102. if (!empty($value)) {
  103. $newValuesArr[$field] = $value;
  104. }
  105. }
  106. $this->resourceArray = array_merge($this->resourceArray, $newValuesArr);
  107. $this->parent->fromArray($this->resourceArray);
  108. $this->parent->set('template',$defaultTemplate);
  109. $this->resource->set('template',$defaultTemplate);
  110. $this->getResourceGroups();
  111. /* check FC rules */
  112. $overridden = $this->checkFormCustomizationRules($this->parent,true);
  113. } else {
  114. $this->resourceArray = array_merge($this->resourceArray, $reloadData);
  115. $this->resourceArray['resourceGroups'] = array();
  116. $this->resourceArray['syncsite'] = true;
  117. $this->resourceArray['resource_groups'] = $this->modx->getOption('resource_groups',
  118. $this->resourceArray, array());
  119. $this->resourceArray['resource_groups'] = is_array($this->resourceArray['resource_groups']) ?
  120. $this->resourceArray['resource_groups'] :
  121. $this->modx->fromJSON($this->resourceArray['resource_groups']);
  122. if (is_array($this->resourceArray['resource_groups'])) {
  123. foreach ($this->resourceArray['resource_groups'] as $resourceGroup) {
  124. $this->resourceArray['resourceGroups'][] = array(
  125. $resourceGroup['id'],
  126. $resourceGroup['name'],
  127. $resourceGroup['access'],
  128. );
  129. }
  130. }
  131. unset($this->resourceArray['resource_groups']);
  132. $this->resource->fromArray($reloadData); // We should have in Reload Data everything needed to do form customization checkings
  133. /* check FC rules */
  134. $overridden = $this->checkFormCustomizationRules($this->resource,true); // This "forParent" doesn't seems logical for me, but it seems that all "resource/create" rules require this (see /core/model/modx/processors/security/forms/set/import.php for example)
  135. }
  136. /* apply FC rules */
  137. $this->resourceArray = array_merge($this->resourceArray,$overridden);
  138. /* handle checkboxes and defaults */
  139. $this->resourceArray['published'] = isset($this->resourceArray['published']) && intval($this->resourceArray['published']) == 1 ? true : false;
  140. $this->resourceArray['hidemenu'] = isset($this->resourceArray['hidemenu']) && intval($this->resourceArray['hidemenu']) == 1 ? true : false;
  141. $this->resourceArray['isfolder'] = isset($this->resourceArray['isfolder']) && intval($this->resourceArray['isfolder']) == 1 ? true : false;
  142. $this->resourceArray['richtext'] = isset($this->resourceArray['richtext']) && intval($this->resourceArray['richtext']) == 1 ? true : false;
  143. $this->resourceArray['searchable'] = isset($this->resourceArray['searchable']) && intval($this->resourceArray['searchable']) == 1 ? true : false;
  144. $this->resourceArray['cacheable'] = isset($this->resourceArray['cacheable']) && intval($this->resourceArray['cacheable']) == 1 ? true : false;
  145. $this->resourceArray['deleted'] = isset($this->resourceArray['deleted']) && intval($this->resourceArray['deleted']) == 1 ? true : false;
  146. $this->resourceArray['uri_override'] = isset($this->resourceArray['uri_override']) && intval($this->resourceArray['uri_override']) == 1 ? true : false;
  147. $this->resourceArray['syncsite'] = isset($this->resourceArray['syncsite']) && intval($this->resourceArray['syncsite']) == 1 ? true : false;
  148. if (!empty($this->resourceArray['parent'])) {
  149. if ($this->parent->get('id') == $this->resourceArray['parent']) {
  150. $this->resourceArray['parent_pagetitle'] = $this->modx->stripTags($this->parent->get('pagetitle'));
  151. } else {
  152. /** @var modResource $overriddenParent */
  153. $overriddenParent = $this->modx->getObject('modResource',$this->resourceArray['parent']);
  154. if ($overriddenParent) {
  155. $this->resourceArray['parent_pagetitle'] = $this->modx->stripTags($overriddenParent->get('pagetitle'));
  156. }
  157. }
  158. }
  159. /* get TVs */
  160. $this->loadTVs($reloadData);
  161. /* single-use token for creating resource */
  162. $this->setResourceToken();
  163. return $placeholders;
  164. }
  165. /**
  166. * Return the default template for this resource
  167. *
  168. * @return int
  169. */
  170. public function getDefaultTemplate() {
  171. $defaultTemplate = (isset($this->scriptProperties['template']) ? $this->scriptProperties['template'] : (!empty($this->parent->id) ? $this->parent->get('template') : $this->context->getOption('default_template', 0, $this->modx->_userConfig)));
  172. $userGroups = $this->modx->user->getUserGroups();
  173. $c = $this->modx->newQuery('modActionDom');
  174. $c->innerJoin('modFormCustomizationSet','FCSet');
  175. $c->innerJoin('modFormCustomizationProfile','Profile','FCSet.profile = Profile.id');
  176. $c->leftJoin('modFormCustomizationProfileUserGroup','ProfileUserGroup','Profile.id = ProfileUserGroup.profile');
  177. $c->leftJoin('modFormCustomizationProfile','UGProfile','UGProfile.id = ProfileUserGroup.profile');
  178. $c->where(array(
  179. 'modActionDom.action' => 'resource/create',
  180. 'modActionDom.name' => 'template',
  181. 'modActionDom.container' => 'modx-panel-resource',
  182. 'modActionDom.rule' => 'fieldDefault',
  183. 'modActionDom.active' => true,
  184. 'FCSet.active' => true,
  185. 'Profile.active' => true,
  186. ));
  187. $c->where(array(
  188. array(
  189. 'ProfileUserGroup.usergroup:IN' => $userGroups,
  190. array(
  191. 'OR:ProfileUserGroup.usergroup:IS' => null,
  192. 'AND:UGProfile.active:=' => true,
  193. ),
  194. ),
  195. 'OR:ProfileUserGroup.usergroup:=' => null,
  196. ),xPDOQuery::SQL_AND,null,2);
  197. /** @var modActionDom $fcDt see http://tracker.modx.com/issues/9592 */
  198. $fcDtColl = $this->modx->getCollection('modActionDom',$c);
  199. if ($fcDtColl) {
  200. if ($this->parent) { /* ensure get all parents */
  201. $p = $this->parent ? $this->parent->get('id') : 0;
  202. $parentIds = $this->modx->getParentIds($p,10,array(
  203. 'context' => $this->parent->get('context_key'),
  204. ));
  205. $parentIds[] = $p;
  206. $parentIds = array_unique($parentIds);
  207. } else {
  208. $parentIds = array(0);
  209. }
  210. /* Check for any FC rules relevant to this page's parents */
  211. foreach ($fcDtColl as $fcDt) {
  212. $constraintField = $fcDt->get('constraint_field');
  213. if (($constraintField == 'id' || $constraintField == 'parent') && in_array($fcDt->get('constraint'),$parentIds)) {
  214. $defaultTemplate = $fcDt->get('value');
  215. } else if (empty($constraintField)) {
  216. $defaultTemplate = $fcDt->get('value');
  217. }
  218. }
  219. }
  220. return $defaultTemplate;
  221. }
  222. /**
  223. * Return the pagetitle
  224. *
  225. * @return string
  226. */
  227. public function getPageTitle() {
  228. return $this->modx->lexicon('document_new');
  229. }
  230. /**
  231. * Return the location of the template file
  232. * @return string
  233. */
  234. public function getTemplateFile() {
  235. return 'resource/create.tpl';
  236. }
  237. }
  238. class DocumentCreateManagerController extends ResourceCreateManagerController {}