| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065 |
- <?php
- /*
- * This file is part of MODX Revolution.
- *
- * Copyright (c) MODX, LLC. All Rights Reserved.
- *
- * For complete copyright and license information, see the COPYRIGHT and LICENSE
- * files found in the top-level directory of this distribution.
- */
- /**
- * Abstract class for manager controllers. Not to be initialized directly; must be extended by the implementing
- * controller.
- *
- * @package modx
- */
- abstract class modManagerController {
- /** @var modX A reference to the modX object */
- public $modx;
- /** @var array A configuration array of options related to this controller's action object. */
- public $config = array();
- /** @var bool Set to false to prevent loading of the header HTML. */
- public $loadHeader = true;
- /** @var bool Set to false to prevent loading of the footer HTML. */
- public $loadFooter = true;
- /** @var bool Set to false to prevent loading of the base MODExt JS classes. */
- public $loadBaseJavascript = true;
- /** @var array An array of possible paths to this controller's templates directory. */
- public $templatesPaths = array();
- /** @var array An array of possible paths to this controller's directory. */
- public $controllersPaths;
- /** @var modContext The current working context. */
- public $workingContext;
- /** @var modMediaSource The default media source for the user */
- public $defaultSource;
- /** @var string The current output content */
- public $content = '';
- /** @var array An array of request parameters sent to the controller */
- public $scriptProperties = array();
- /** @var array An array of css/js/html to load into the HEAD of the page */
- public $head = array('css' => array(),'js' => array(),'html' => array(),'lastjs' => array());
- /** @var array An array of placeholders that are being set to the page */
- public $placeholders = array();
- /** @var string Any Form Customization rule output that was created. */
- protected $ruleOutput = array();
- /** @var string The current manager theme. */
- protected $theme = 'default';
- /** @var string The pagetitle for this controller. */
- protected $title = '';
- /** @var bool Whether or not a failure message was sent by this controller. */
- protected $isFailure = false;
- /** @var string The failure message, if existent, for this controller. */
- protected $failureMessage = '';
- /**
- * The constructor for the modManagerController class.
- *
- * @param modX $modx A reference to the modX object.
- * @param array $config A configuration array of options related to this controller's action object.
- */
- function __construct(modX &$modx,$config = array()) {
- $this->modx =& $modx;
- $this->config = !empty($config) && is_array($config) ? $config : array();
- }
- /**
- * Can be used to provide custom methods prior to processing
- * @return void
- */
- public function initialize() {}
- /**
- * Return the proper instance of the derived class. This can be used to override how the manager loads a controller
- * class; for example, when handling derivative classes with class_key settings.
- *
- * @static
- * @param modX $modx A reference to the modX object.
- * @param string $className The name of the class that is being requested.
- * @param array $config A configuration array of options related to this controller's action object.
- * @return The class specified by $className
- */
- public static function getInstance(modX &$modx, $className, array $config = array()) {
- /** @var modManagerController $controller */
- $controller = new $className($modx,$config);
- return $controller;
- }
- /**
- * Sets the properties array for this controller
- * @param array $properties
- * @return void
- */
- public function setProperties(array $properties) {
- $this->scriptProperties = $properties;
- }
- /**
- * Set a property for this controller
- * @param string $key
- * @param mixed $value
- * @return void
- */
- public function setProperty($key,$value) {
- $this->scriptProperties[$key] = $value;
- }
- /**
- * Prepares the language placeholders
- */
- public function prepareLanguage() {
- $this->modx->lexicon->load('action');
- $languageTopics = $this->getLanguageTopics();
- foreach ($languageTopics as $topic) {
- $this->modx->lexicon->load($topic);
- }
- $this->setPlaceholder('_lang_topics',implode(',',$languageTopics));
- $this->setPlaceholder('_lang', $this->modx->lexicon->fetch());
- }
- /**
- * Render the controller.
- *
- * @return string
- */
- public function render() {
- if (!$this->checkPermissions()) {
- return $this->modx->error->failure($this->modx->lexicon('access_denied'));
- }
- $this->modx->invokeEvent('OnBeforeManagerPageInit',array(
- 'action' => $this->config,
- ));
- $this->theme = $this->modx->getOption('manager_theme',null,'default',true);
- $this->prepareLanguage();
- $this->setPlaceholder('_ctx',$this->modx->context->get('key'));
- $this->loadControllersPath();
- $this->loadTemplatesPath();
- $content = '';
- $this->registerBaseScripts();
- $this->checkFormCustomizationRules();
- $this->setPlaceholder('_config',$this->modx->config);
- $this->setCssURLPlaceholders();
- /* help url */
- $helpUrl = $this->getHelpUrl();
- $this->addHtml('<script type="text/javascript">MODx.helpUrl = "'.($helpUrl).'"</script>');
- $this->modx->invokeEvent('OnManagerPageBeforeRender',array('controller' => &$this));
- $placeholders = $this->process($this->scriptProperties);
- if (!$this->isFailure && !empty($placeholders) && is_array($placeholders)) {
- $this->setPlaceholders($placeholders);
- } elseif (!empty($placeholders)) {
- $content = $placeholders;
- }
- if (!$this->isFailure) {
- $this->loadCustomCssJs();
- }
- $this->firePreRenderEvents();
- /* handle FC rules */
- if (!empty($this->ruleOutput)) {
- $this->addHtml(implode("\n",$this->ruleOutput));
- }
- /* register CSS/JS */
- $this->registerCssJs();
- $this->setPlaceholder('_pagetitle',$this->getPageTitle());
- $this->content = '';
- if ($this->loadHeader) {
- $this->content .= $this->getHeader();
- }
- $tpl = $this->getTemplateFile();
- if ($this->isFailure) {
- $this->setPlaceholder('_e', $this->modx->error->failure($this->failureMessage));
- $content = $this->fetchTemplate('error.tpl');
- } else if (!empty($tpl)) {
- $content = $this->fetchTemplate($tpl);
- }
- $this->content .= $content;
- if ($this->loadFooter) {
- $this->content .= $this->getFooter();
- }
- $this->firePostRenderEvents();
- $this->modx->invokeEvent('OnManagerPageAfterRender',array('controller' => &$this));
- return $this->content;
- }
- public function getHelpUrl() {
- return '';
- }
- /**
- * @return void
- */
- protected function assignPlaceholders() {
- foreach ($this->placeholders as $k => $v) {
- $this->modx->smarty->assign($k,$v);
- }
- }
- /**
- * Set a placeholder for this controller's template
- *
- * @param string $k The key of the placeholder
- * @param mixed $v The value of the placeholder
- * @return void
- */
- public function setPlaceholder($k,$v) {
- $this->placeholders[$k] = $v;
- $this->modx->smarty->assign($k,$v);
- }
- /**
- * Set an array of placeholders
- *
- * @param array $keys
- * @return void
- */
- public function setPlaceholders($keys) {
- foreach ($keys as $k => $v) {
- $this->placeholders[$k] = $v;
- $this->modx->smarty->assign($k,$v);
- }
- }
- /**
- * Get all the set placeholders
- * @return array
- */
- public function getPlaceholders() {
- return $this->placeholders;
- }
- /**
- * Get a specific placeholder set
- * @param string $k
- * @param mixed $default
- * @return mixed
- */
- public function getPlaceholder($k,$default = null) {
- return isset($this->placeholders[$k]) ? $this->placeholders[$k] : $default;
- }
- /**
- * Fetch the template content
- * @param string $tpl The path to the template
- * @return string The output of the template
- */
- public function fetchTemplate($tpl) {
- $templatePath = '';
- if (is_array($this->templatesPaths)) {
- foreach ($this->templatesPaths as $path) {
- if (file_exists($path.$tpl)) {
- $templatePath = $path;
- break;
- }
- }
- }
- $this->modx->smarty->setTemplatePath($templatePath);
- return $this->modx->smarty->fetch($tpl);
- }
- /**
- * Load another manual controller file (such as header/footer)
- *
- * @param $controller
- * @param bool $coreOnly
- * @return mixed|string
- */
- public function loadController($controller,$coreOnly = false) {
- /** @var modX $modx */
- $modx =& $this->modx;
- $paths = $this->getControllersPaths($coreOnly);
- $o = '';
- foreach ($paths as $path) {
- if (file_exists($path.$controller)) {
- $o = include_once $path.$controller;
- break;
- }
- }
- return $o;
- }
- /**
- * Set a failure on this controller. This will return the error message.
- *
- * @param string $message
- * @return void
- */
- public function failure($message) {
- $this->isFailure = true;
- $this->failureMessage .= $message;
- }
- /**
- * Load the path to this controller's template's directory. Only override this if you want to override default
- * behavior; otherwise, overriding getTemplatesPath is preferred.
- *
- * @return string
- */
- public function loadTemplatesPath() {
- if (empty($this->templatesPaths)) {
- $templatesPaths = $this->getTemplatesPaths();
- if (is_string($templatesPaths)) {
- $templatesPaths = array($templatesPaths);
- }
- $this->setTemplatePaths($templatesPaths);
- }
- return $this->templatesPaths;
- }
- /**
- * Set the possible template paths for this controller
- *
- * @param array $paths
- * @return void
- */
- public function setTemplatePaths(array $paths) {
- $this->templatesPaths = $paths;
- }
- /**
- * Load an array of possible paths to this controller's directory. Only override this if you want to override
- * default behavior; otherwise, overriding getControllersPath is preferred.
- *
- * @return array
- */
- public function loadControllersPath() {
- if (empty($this->controllersPaths)) {
- $this->controllersPaths = $this->getControllersPaths();
- }
- return $this->controllersPaths;
- }
- /**
- * Get the path to this controller's directory. Override this to point to a custom directory.
- *
- * @param bool $coreOnly Ensure that it grabs the path from the core namespace only.
- * @return array
- */
- public function getControllersPaths($coreOnly = false) {
- if (!empty($this->config['namespace']) && $this->config['namespace'] != 'core' && !$coreOnly) { /* for non-core controllers */
- $managerPath = $this->modx->getOption('manager_path',null,MODX_MANAGER_PATH);
- $paths[] = $this->config['namespace_path'].'controllers/'.$this->theme.'/';
- $paths[] = $this->config['namespace_path'].'controllers/default/';
- $paths[] = $this->config['namespace_path'].'controllers/';
- $paths[] = $this->config['namespace_path'].$this->theme.'/';
- $paths[] = $this->config['namespace_path'].'default/';
- $paths[] = $this->config['namespace_path'];
- $paths[] = $managerPath.'controllers/'.$this->theme.'/';
- $paths[] = $managerPath.'controllers/default/';
- } else { /* for core controllers only */
- $managerPath = $this->modx->getOption('manager_path',null,MODX_MANAGER_PATH);
- $paths[] = $managerPath.'controllers/'.$this->theme.'/';
- $paths[] = $managerPath.'controllers/default/';
- }
- return $paths;
- }
- /**
- * Get an array of possible paths to this controller's template's directory.
- * Override this to point to a custom directory.
- *
- * @param bool $coreOnly Ensure that it grabs the path from the core namespace only.
- * @return array|string
- */
- public function getTemplatesPaths($coreOnly = false) {
- /* extras */
- if (!empty($this->config['namespace']) && $this->config['namespace'] != 'core' && !$coreOnly) {
- $namespacePath = $this->config['namespace_path'];
- $paths[] = $namespacePath . 'templates/'.$this->theme.'/';
- $paths[] = $namespacePath . 'templates/default/';
- $paths[] = $namespacePath . 'templates/';
- }
- $managerPath = $this->modx->getOption('manager_path',null,MODX_MANAGER_PATH);
- $paths[] = $managerPath . 'templates/'.$this->theme.'/';
- $paths[] = $managerPath . 'templates/default/';
- $paths = array_unique($paths);
- return $paths;
- }
- /**
- * Get an array of possible URLs to the template's directory.
- * Override this to point to a custom directory.
- *
- * @param bool $specificThemeOnly Return URL only to theme specified in system settings
- * @return array
- */
- public function getTemplatesUrls($specificThemeOnly = false) {
- $urls = array();
- $managerUrl = $this->modx->getOption('manager_url', null, MODX_MANAGER_URL);
- $urls[] = $managerUrl . 'templates/'.$this->theme.'/';
- if ($specificThemeOnly === false) {
- $urls[] = $managerUrl . 'templates/default/';
- }
- return $urls;
- }
- /**
- * Do permission checking in this method. Returning false will present a "permission denied" message.
- *
- * @abstract
- * @return boolean
- */
- abstract public function checkPermissions();
- /**
- * Process the controller, returning an array of placeholders to set.
- *
- * @abstract
- * @param array $scriptProperties A array of REQUEST parameters.
- * @return mixed Either an error or output string, or an array of placeholders to set.
- */
- abstract public function process(array $scriptProperties = array());
- /**
- * Return a string to set as the controller's page title.
- *
- * @abstract
- * @return string
- */
- abstract public function getPageTitle();
- /**
- * Register any custom CSS or JS in this method.
- * @abstract
- * @return void
- */
- abstract public function loadCustomCssJs();
- /**
- * Return the relative path to the template file to load
- * @abstract
- * @return string
- */
- abstract public function getTemplateFile();
- /**
- * Specify an array of language topics to load for this controller
- *
- * @return array
- */
- public function getLanguageTopics() {
- return array();
- }
- /**
- * Can be used to fire events after all the CSS/JS is loaded for a page
- * @return void
- */
- public function firePostRenderEvents() {}
- /**
- * Fire any pre-render events for the controller
- * @return void
- */
- public function firePreRenderEvents() {}
- /**
- * Get the page header for the controller.
- *
- * @return string
- */
- public function getHeader() {
- $this->loadController('header.php',true);
- return $this->fetchTemplate('header.tpl');
- }
- /**
- * Get the page footer for the controller.
- * @return string
- */
- public function getFooter() {
- $this->loadController('footer.php',true);
- return $this->fetchTemplate('footer.tpl');
- }
- /**
- * Registers the core and base JS scripts
- *
- * @access public
- * @return void
- */
- public function registerBaseScripts() {
- $managerUrl = $this->modx->getOption('manager_url');
- $externals = array();
- if ($this->loadBaseJavascript) {
- $compressJs = (boolean)$this->modx->getOption('compress_js',null,true);
- $this->modx->setOption('compress_js',$compressJs);
- if ($compressJs) {
- $externals[] = $managerUrl . 'assets/modext/modx.jsgrps-min.js';
- }
- else {
- $externals[] = $managerUrl . 'assets/modext/core/modx.localization.js';
- $externals[] = $managerUrl . 'assets/modext/util/utilities.js';
- $externals[] = $managerUrl . 'assets/modext/util/datetime.js';
- $externals[] = $managerUrl . 'assets/modext/util/uploaddialog.js';
- $externals[] = $managerUrl . 'assets/modext/util/fileupload.js';
- $externals[] = $managerUrl . 'assets/modext/util/superboxselect.js';
- $externals[] = $managerUrl . 'assets/modext/core/modx.component.js';
- $externals[] = $managerUrl . 'assets/modext/core/modx.view.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/core/modx.button.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/core/modx.searchbar.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/core/modx.panel.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/core/modx.tabs.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/core/modx.window.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/core/modx.combo.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/core/modx.grid.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/core/modx.console.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/core/modx.portal.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/windows.js';
- $externals[] = $managerUrl . 'assets/fileapi/FileAPI.js';
- $externals[] = $managerUrl . 'assets/modext/util/multiuploaddialog.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/core/tree/modx.tree.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/core/tree/modx.tree.treeloader.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/modx.treedrop.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/core/modx.tree.asynctreenode.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/resource/modx.tree.resource.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/element/modx.tree.element.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/system/modx.tree.directory.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/system/modx.panel.filetree.js';
- $externals[] = $managerUrl . 'assets/modext/widgets/media/modx.browser.js';
- $externals[] = $managerUrl.'assets/modext/core/modx.layout.js';
- }
- $this->loadLayout($externals);
- if ($this->modx->getOption('compress_css',null,true)) {
- $this->modx->setOption('compress_css',true);
- }
- $o = '';
- // Add script tags for the required javascript
- foreach ($externals as $js) {
- $o .= '<script type="text/javascript" src="'.$js.'"></script>'."\n";
- }
- // Get the state and user token for adding to the init script
- $state = $this->getDefaultState();
- if (!empty($state)) {
- $state = 'MODx.defaultState = '.$this->modx->toJSON($state).';';
- } else {
- $state = '';
- }
- $layout = '';
- if (!$this instanceof BrowserManagerController) {
- $siteId = $this->modx->user->getUserToken('mgr');
- $layout = 'MODx.load({xtype: "modx-layout",accordionPanels: MODx.accordionPanels || [],auth: "'.$siteId.'"});';
- }
- $o .= <<<HTML
- <script type="text/javascript">
- Ext.onReady(function() {
- {$state}
- {$layout}
- });
- </script>
- HTML;
- $this->modx->smarty->assign('maincssjs', $o);
- }
- }
- /**
- * Load theme specific layout.js if found, fallback to default layout
- *
- * @param array $externals An array of assets to load
- *
- * @return void
- */
- public function loadLayout(array &$externals) {
- $templatesUrl = $this->modx->getOption('manager_url', null, MODX_MANAGER_URL) . 'templates/';
- $themePath = MODX_MANAGER_PATH . "templates/{$this->theme}";
- $layoutFile = '/js/layout.js';
- if (file_exists($themePath . $layoutFile)) {
- // Apply to both custom themes and "default" theme
- $externals[] = $templatesUrl . $this->theme . $layoutFile;
- } elseif ($this->theme !== 'default') {
- // Load default layout for custom themes without a custom layout.js
- $externals[] = $templatesUrl . 'default' . $layoutFile;
- }
- }
- /**
- * Get the default state for the UI
- * @return array|mixed|string
- */
- public function getDefaultState() {
- /** @var modProcessorResponse $response */
- $response = $this->modx->runProcessor('system/registry/register/read',array(
- 'register' => 'state',
- 'topic' => '/ys/user-'.$this->modx->user->get('id').'/',
- 'include_keys' => true,
- 'poll_interval' => 1,
- 'poll_limit' => 1,
- 'remove_read' => false,
- 'show_filename' => false,
- 'time_limit' => 10,
- ));
- $obj = $response->getMessage();
- if (!empty($obj)) {
- $obj = $this->modx->fromJSON($obj);
- } else {
- $obj = array();
- }
- return $obj;
- }
- /**
- * Grabs a stripped version of modx to prevent caching of JS after upgrades
- *
- * @access private
- * @return string The parsed version string
- */
- private function _prepareVersionPostfix() {
- $version = $this->modx->getVersionData();
- return str_replace(array('.','-'),'',$version['full_version']);
- }
- /**
- * Appends a version postfix to a script tag
- *
- * @access private
- * @param string $str The script tag to append the version to
- * @param string $version The version to append
- * @return string The adjusted script tag
- */
- private function _postfixVersionToScript($str,$version) {
- $pos = strpos($str,'.js');
- $pos2 = strpos($str,'src="'); /* only apply to externals */
- if ($pos && $pos2) {
- $s = substr($str,0,strpos($str,'"></script>'));
- if (!empty($s) && substr($s,strlen($s)-3,strlen($s)) == '.js') {
- $str = $s.'?v='.$version.'"></script>';
- }
- }
- return $str;
- }
- /**
- * Registers CSS/JS to manager interface
- */
- public function registerCssJs() {
- $this->_prepareHead();
- $versionPostFix = $this->_prepareVersionPostfix();
- $jsToCompress = array();
- foreach ($this->head['js'] as $js) {
- $jsToCompress[] = $js;
- }
- $cssjs = array();
- if (!empty($jsToCompress)) {
- foreach ($jsToCompress as $scr) {
- $cssjs[] = '<script src="'.$scr.'" type="text/javascript"></script>';
- }
- }
- $cssToCompress = array();
- foreach ($this->head['css'] as $css) {
- $cssToCompress[] = $css;
- }
- if (!empty($cssToCompress)) {
- foreach ($cssToCompress as $scr) {
- $cssjs[] = '<link href="'.$scr.'" rel="stylesheet" type="text/css" />';
- }
- }
- foreach ($this->head['html'] as $html) {
- $cssjs[] = $html;
- }
- foreach ($this->modx->sjscripts as $scr) {
- $scr = $this->_postfixVersionToScript($scr,$versionPostFix);
- $cssjs[] = $scr;
- }
- $lastjs = array();
- foreach ($this->head['lastjs'] as $js) {
- $lastjs[] = $js;
- }
- if (!empty($lastjs)) {
- foreach ($lastjs as $scr) {
- $cssjs[] = '<script src="'.$scr.'" type="text/javascript"></script>';
- }
- }
- $this->modx->smarty->assign('cssjs',$cssjs);
- }
- /**
- * Prepare the set html/css/js to be added
- * @return void
- */
- private function _prepareHead() {
- $this->head['js'] = array_unique($this->head['js']);
- $this->head['html'] = array_unique($this->head['html']);
- $this->head['css'] = array_unique($this->head['css']);
- $this->head['lastjs'] = array_unique($this->head['lastjs']);
- }
- /**
- * Add an external Javascript file to the head of the page
- *
- * @param string $script
- * @return void
- */
- public function addJavascript($script) {
- $this->head['js'][] = $script;
- }
- /**
- * Add a block of HTML to the head of the page
- *
- * @param string $script
- * @return void
- */
- public function addHtml($script) {
- $this->head['html'][] = $script;
- }
- /**
- * Add a external CSS file to the head of the page
- * @param string $script
- * @return void
- */
- public function addCss($script) {
- $this->head['css'][] = $script;
- }
- /**
- * Add an external Javascript file to the head of the page
- *
- * @param string $script
- * @return void
- */
- public function addLastJavascript($script) {
- $this->head['lastjs'][] = $script;
- }
- /**
- * Checks Form Customization rules for an object.
- *
- * @param xPDOObject $obj If passed, will validate against for rules with constraints.
- * @param bool $forParent No longer used - filtering only happens by controller
- * @return array
- */
- public function checkFormCustomizationRules(&$obj = null, $forParent = false) {
- $overridden = array();
- if ($this->modx->getOption('form_customization_use_all_groups',null,false)) {
- $userGroups = $this->modx->user->getUserGroups();
- } else {
- $primaryGroup = $this->modx->user->getPrimaryGroup();
- if ($primaryGroup) {
- $userGroups = array($primaryGroup->get('id'));
- }
- }
- $c = $this->modx->newQuery('modActionDom');
- $c->innerJoin('modFormCustomizationSet','FCSet');
- $c->innerJoin('modFormCustomizationProfile','Profile','FCSet.profile = Profile.id');
- $c->leftJoin('modFormCustomizationProfileUserGroup','ProfileUserGroup','Profile.id = ProfileUserGroup.profile');
- $c->leftJoin('modFormCustomizationProfile','UGProfile','UGProfile.id = ProfileUserGroup.profile');
- // Filter on the controller (action).
- $controller = array_key_exists('controller', $this->config) ? $this->config['controller'] : '';
- if (strpos($controller, '/') !== false) {
- // For multi-level controllers (e.g. resource/create), we get the last part
- // of the controller name to also search for a wildcard (e.g. resource/*)
- $wildController = substr($controller, 0, strrpos($controller, '/')) . '/*';
- $c->where(array(
- 'modActionDom.action:IN' => array($controller, $wildController),
- ));
- }
- else {
- $c->where(array(
- 'modActionDom.action' => array_key_exists('controller',$this->config) ? $this->config['controller'] : '',
- ));
- }
- $c->where(array(
- 'FCSet.active' => true,
- 'Profile.active' => true,
- ));
- if (!empty($userGroups)) {
- $c->where(array(
- array(
- 'ProfileUserGroup.usergroup:IN' => $userGroups,
- array(
- 'OR:ProfileUserGroup.usergroup:IS' => null,
- 'AND:UGProfile.active:=' => true,
- ),
- ),
- 'OR:ProfileUserGroup.usergroup:=' => null,
- ),xPDOQuery::SQL_AND,null,2);
- }
- $c->select($this->modx->getSelectColumns('modActionDom', 'modActionDom'));
- $c->select($this->modx->getSelectColumns('modFormCustomizationSet', 'FCSet', '', array(
- 'constraint_class',
- 'constraint_field',
- 'constraint',
- 'template'
- )));
- $c->sortby('modActionDom.rank','ASC');
- $domRules = $this->modx->getCollection('modActionDom',$c);
- $rules = array();
- /** @var modActionDom $rule */
- foreach ($domRules as $rule) {
- $template = $rule->get('template');
- if (!empty($template) && $obj) {
- if ($template != $obj->get('template')) continue;
- }
- $constraintClass = $rule->get('constraint_class');
- if (!empty($constraintClass)) {
- if (empty($obj) || !($obj instanceof $constraintClass)) continue;
- $constraintField = $rule->get('constraint_field');
- $constraint = $rule->get('constraint');
- $constraintList = explode(',', $constraint);
- $constraintList = array_map('trim', $constraintList);
- if (($obj->get($constraintField) != $constraint) && (!in_array($obj->get($constraintField), $constraintList))) {
- continue;
- }
- }
- if ($rule->get('rule') == 'fieldDefault') {
- $field = $rule->get('name');
- if ($field == 'modx-resource-content') $field = 'content';
- $overridden[$field] = $rule->get('value');
- if ($field == 'parent-cmb') {
- $overridden['parent'] = (int)$rule->get('value');
- $overridden['parent-cmb'] = (int)$rule->get('value');
- }
- }
- $r = $rule->apply();
- if (!empty($r)) $rules[] = $r;
- }
- if (!empty($rules)) {
- $this->ruleOutput[] = '<script type="text/javascript">Ext.onReady(function() {'.implode("\n",$rules).'});</script>';
- }
- return $overridden;
- }
- /**
- * Load the working context for this controller.
- *
- * @return modContext|string
- */
- public function loadWorkingContext() {
- $wctx = !empty($_GET['wctx']) ? $_GET['wctx'] : $this->modx->context->get('key');
- if (!empty($wctx)) {
- $this->workingContext = $this->modx->getContext($wctx);
- if (!$this->workingContext) {
- $this->failure($this->modx->lexicon('permission_denied'));
- }
- } else {
- $this->workingContext =& $this->modx->context;
- }
- return $this->workingContext;
- }
- /**
- * Adds a topic to the JS language array
- * @param string $topic
- * @return string
- */
- public function addLexiconTopic($topic) {
- $this->modx->lexicon->load($topic);
- $langTopics = $this->getPlaceholder('_lang_topics');
- $langTopics = explode(',',$langTopics);
- $langTopics[] = $topic;
- $langTopics = implode(',',$langTopics);
- $this->setPlaceholder('_lang_topics',$langTopics);
- return $langTopics;
- }
- public function setCssURLPlaceholders()
- {
- $managerUrl = $this->modx->getOption('manager_url', null, MODX_MANAGER_URL);
- $managerPath = $this->modx->getOption('manager_path',null,MODX_MANAGER_PATH);
- $index = false;
- $login = false;
- if ($this->theme != 'default') {
- if (file_exists($managerPath . 'templates/' . $this->theme . '/css/index.css')) {
- $this->setPlaceholder('indexCss', $managerUrl . 'templates/' . $this->theme . '/css/index.css');
- $index = true;
- }
- if (file_exists($managerPath . 'templates/' . $this->theme . '/css/login.css')) {
- $this->setPlaceholder('loginCss', $managerUrl . 'templates/' . $this->theme . '/css/login.css');
- $login = true;
- }
- }
- $versionToken = hash('adler32', $this->modx->getOption('settings_version') . $this->modx->uuid );
- $this->setPlaceholder('versionToken', $versionToken);
- if (!$index) {
- $this->setPlaceholder('indexCss', $managerUrl . 'templates/default/css/index.css');
- }
- if (!$login) {
- $this->setPlaceholder('loginCss', $managerUrl . 'templates/default/css/login.css');
- }
- }
- }
- /**
- * Utility abstract class for usage by Extras that has a subrequest handler that does auto-routing by the &action
- * REQUEST parameter. You must extend this class in your Extra to use it.
- *
- * @abstract
- * @package modx
- */
- abstract class modExtraManagerController extends modManagerController {
- /**
- * Define the default controller action for this namespace
- * @static
- * @return string A default controller action
- */
- public static function getDefaultController() { return 'index'; }
- /**
- * Get an instance of this extra controller
- * @static
- * @param modX $modx A reference to the modX object
- * @param string $className The string className that is being requested to load
- * @param array $config An array of configuration options built from the modAction object
- * @return modManagerController A newly created modManagerController instance
- */
- public static function getInstanceDeprecated(modX &$modx, $className, array $config = array()) {
- $action = call_user_func(array($className,'getDefaultController'));
- if (isset($_REQUEST['action'])) {
- $action = str_replace(array('../','./','.','-','@'),'',$_REQUEST['action']);
- }
- $className = self::getControllerClassName($action,$config['namespace']);
- $classPath = $config['namespace_path'].'controllers/'.$action.'.class.php';
- require_once $classPath;
- /** @var modManagerController $controller */
- $controller = new $className($modx,$config);
- return $controller;
- }
- /**
- * Return the class name of a controller given the action
- * @static
- * @param string $action The action name, eg: "home" or "create"
- * @param string $namespace The namespace of the Exra
- * @param string $postFix The string to postfix to the class name
- * @return string A full class name of the controller class
- */
- public static function getControllerClassName($action,$namespace = '',$postFix = 'ManagerController') {
- $className = explode('/',$action);
- $o = array();
- foreach ($className as $k) {
- $o[] = ucfirst(str_replace(array('.','_','-'),'',$k));
- }
- return ucfirst($namespace).implode('',$o).$postFix;
- }
- /**
- * Do any page-specific logic and/or processing here
- * @param array $scriptProperties
- * @return void
- */
- public function process(array $scriptProperties = array()) {}
- /**
- * The page title for this controller
- * @return string The string title of the page
- */
- public function getPageTitle() { return ''; }
- /**
- * Loads any page-specific CSS/JS for the controller
- * @return void
- */
- public function loadCustomCssJs() {}
- /**
- * Specify the location of the template file
- * @return string The absolute path to the template file
- */
- public function getTemplateFile() { return ''; }
- /**
- * Check whether the active user has access to view this page
- * @return bool True if the user passes permission checks
- */
- public function checkPermissions() { return true;}
- }
- /**
- * A base manager controller to implement, which makes use of the regular parser
- */
- abstract class modParsedManagerController extends modExtraManagerController {
- /**
- * The request HTTP method
- *
- * @var string
- */
- protected $method = 'GET';
- public function initialize() {
- parent::initialize();
- // Let's check the HTTP method to display a different content based on it (ie. when we submit a form)
- $this->method = filter_input(INPUT_SERVER, 'REQUEST_METHOD');
- // Some hack to put the HTML content in its right place so ExtJS can resize the main content "area" properly
- $this->addHtml(<<<HTML
- <script>
- Ext.onReady(function() {
- var node = document.getElementById('modx-panel-holder').nextElementSibling
- ,content = node.innerHTML;
- node.parentNode.removeChild(node);
- MODx.add({
- xtype: 'box'
- ,html: content
- ,cls: node.className || ''
- ,id: node.id || Ext.id()
- });
- });
- </script>
- HTML
- );
- }
- /**
- * @inheritDoc
- */
- public function render() {
- $html = parent::render();
- // Make controller placeholders available as modx placeholders
- $this->modx->setPlaceholders($this->placeholders, 'ph.');
- // Make script properties available as placeholders too
- $this->modx->setPlaceholders($this->scriptProperties, 'prop.');
- // Make modx parses tags
- $this->modx->getParser()->processElementTags('', $html, true, true);
- return $html;
- }
- }
|