| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850 |
- <?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.
- */
- /**
- * This is the main file to include in your scripts to use MODX.
- *
- * For detailed information on using this class, see {@tutorial modx/modx.pkg}.
- *
- * @package modx
- */
- /* fix for PHP float bug: http://bugs.php.net/bug.php?id=53632 (php 4 <= 4.4.9 and php 5 <= 5.3.4) */
- if (strstr(str_replace('.','',serialize(array_merge($_GET, $_POST, $_COOKIE))), '22250738585072011')) {
- header('Status: 422 Unprocessable Entity');
- die();
- }
- if (!defined('MODX_CORE_PATH')) {
- define('MODX_CORE_PATH', dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR);
- }
- require_once (MODX_CORE_PATH . 'xpdo/xpdo.class.php');
- /**
- * This is the MODX gateway class.
- *
- * It can be used to interact with the MODX framework and serves as a front
- * controller for handling requests to the virtual resources managed by the MODX
- * Content Management Framework.
- *
- * @package modx
- */
- class modX extends xPDO {
- /**
- * The parameter for when a session state is not able to be accessed
- * @const SESSION_STATE_UNAVAILABLE
- */
- const SESSION_STATE_UNAVAILABLE = -1;
- /**
- * The parameter for when a session has not yet been instantiated
- * @const SESSION_STATE_UNINITIALIZED
- */
- const SESSION_STATE_UNINITIALIZED = 0;
- /**
- * The parameter for when a session has been fully initialized
- * @const SESSION_STATE_INITIALIZED
- */
- const SESSION_STATE_INITIALIZED = 1;
- /**
- * The parameter marking when a session is being controlled by an external provider
- * @const SESSION_STATE_EXTERNAL
- */
- const SESSION_STATE_EXTERNAL = 2;
- /**
- * @var modContext The Context represents a unique section of the site which
- * this modX instance is controlling.
- */
- public $context= null;
- /**
- * @var array An array of secondary contexts loaded on demand.
- */
- public $contexts= array();
- /**
- * @var modRequest|modConnectorRequest|modManagerRequest Represents a web request and provides helper methods for
- * dealing with request parameters and other attributes of a request.
- */
- public $request= null;
- /**
- * @var modResponse|modConnectorResponse|modManagerResponse Represents a web response, providing helper methods for
- * managing response header attributes and the body containing the content of
- * the response.
- */
- public $response= null;
- /**
- * @var modParser The modParser registered for this modX instance,
- * responsible for content tag parsing, and loaded only on demand.
- */
- public $parser= null;
- /**
- * @var array An array of supplemental service classes for this modX instance.
- */
- public $services= array ();
- /**
- * @var array A listing of site Resources and Context-specific meta data.
- */
- public $resourceListing= null;
- /**
- * @var array A hierarchy map of Resources.
- */
- public $resourceMap= null;
- /**
- * @var array A lookup listing of Resource alias values and associated
- * Resource Ids
- */
- public $aliasMap= null;
- /**
- * @var modSystemEvent The current event being handled by modX.
- */
- public $event= null;
- /**
- * @var array A map of elements registered to specific events.
- */
- public $eventMap= null;
- /**
- * @var array A map of actions registered to the manager interface.
- */
- public $actionMap= null;
- /**
- * @var array A map of already processed Elements.
- */
- public $elementCache= array ();
- /**
- * @var array An array of key=> value pairs that can be used by any Resource
- * or Element.
- */
- public $placeholders= array ();
- /**
- * @var modResource An instance of the current modResource controlling the
- * request.
- */
- public $resource= null;
- /**
- * @var string The preferred Culture key for the current request.
- */
- public $cultureKey= '';
- /**
- * @var modLexicon Represents a localized dictionary of common words and phrases.
- */
- public $lexicon= null;
- /**
- * @var modUser The current user object, if one is authenticated for the
- * current request and context.
- */
- public $user= null;
- /**
- * @var array Represents the modContentType instances that can be delivered
- * by this modX deployment.
- */
- public $contentTypes= null;
- /**
- * @var mixed The resource id or alias being requested.
- */
- public $resourceIdentifier= null;
- /**
- * @var string The method to use to locate the Resource, 'id' or 'alias'.
- */
- public $resourceMethod= null;
- /**
- * @var boolean Indicates if the resource was generated during this request.
- */
- public $resourceGenerated= false;
- /**
- * @var array Version information for this MODX deployment.
- */
- public $version= null;
- /**
- * @var string Unique site id for each MODX installation.
- */
- public $site_id;
- /**
- * @var string Unique uuid for each MODX installation.
- */
- public $uuid;
- /**
- * @var boolean Indicates if modX has been successfully initialized for a
- * modContext.
- */
- protected $_initialized= false;
- /**
- * @var array An array of javascript content to be inserted into the HEAD
- * of an HTML resource.
- */
- public $sjscripts= array ();
- /**
- * @var array An array of javascript content to be inserted into the BODY
- * of an HTML resource.
- */
- public $jscripts= array ();
- /**
- * @var array An array of already loaded javascript/css code
- */
- public $loadedjscripts= array ();
- /**
- * @var string Stores the virtual path for a request to MODX if the
- * friendly_alias_paths option is enabled.
- */
- public $virtualDir;
- /**
- * @var modErrorHandler|object An error_handler for the modX instance.
- */
- public $errorHandler= null;
- /**
- * @var modError An error response class for the request
- */
- public $error = null;
- /**
- * @var modManagerController A controller object that represents a page in the manager
- */
- public $controller = null;
- /**
- * @var modRegistry $registry
- */
- public $registry;
- /**
- * @var modMail $mail
- */
- public $mail;
- /**
- * @var modRestClient $rest
- */
- public $rest;
- /**
- * @var array $processors An array of loaded processors and their class name
- */
- public $processors = array();
- /**
- * @var array An array of regex patterns regulary cleansed from content.
- */
- public $sanitizePatterns = array(
- 'scripts' => '@<script[^>]*?>.*?</script>@si',
- 'entities' => '@&#(\d+);@',
- 'tags1' => '@\[\[(.*?)\]\]@si',
- 'tags2' => '@(\[\[|\]\])@si',
- );
- /**
- * @var integer An integer representing the session state of modX.
- */
- protected $_sessionState= modX::SESSION_STATE_UNINITIALIZED;
- /**
- * @var array A config array that stores the bootstrap settings.
- */
- protected $_config= null;
- /**
- * @var array A config array that stores the system-wide settings.
- */
- public $_systemConfig= array();
- /**
- * @var array A config array that stores the user settings.
- */
- public $_userConfig= array();
- /**
- * @var int The current log sequence
- */
- protected $_logSequence= 0;
- /**
- * @var array An array of plugins that have been cached for execution
- */
- public $pluginCache= array();
- /**
- * @var array The elemnt source cache used for caching and preparing Element data
- */
- public $sourceCache= array(
- 'modChunk' => array()
- ,'modSnippet' => array()
- ,'modTemplateVar' => array()
- );
- /** @var modCacheManager $cacheManager */
- public $cacheManager;
- /**
- * @deprecated
- * @var modSystemEvent $Event
- */
- public $Event= null;
- /**
- * @deprecated
- * @var string $documentOutput
- */
- public $documentOutput= null;
- /**
- * Keeps an in-memory representation of what deprecated functions have been logged
- * for this request, to avoid spamming the log too often. See the `deprecated` method.
- *
- * @var array
- */
- private $loggedDeprecatedFunctions = array();
- /**
- * Harden the environment against common security flaws.
- *
- * @static
- */
- public static function protect() {
- if (@ ini_get('register_globals') && isset ($_REQUEST)) {
- foreach ($_REQUEST as $key => $value) {
- $GLOBALS[$key] = null;
- unset ($GLOBALS[$key]);
- }
- }
- $targets= array ('PHP_SELF', 'HTTP_USER_AGENT', 'HTTP_REFERER', 'QUERY_STRING');
- foreach ($targets as $target) {
- $_SERVER[$target] = isset ($_SERVER[$target]) ? htmlspecialchars($_SERVER[$target], ENT_QUOTES) : null;
- }
- }
- /**
- * Sanitize values of an array using regular expression patterns.
- *
- * @static
- * @param array $target The target array to sanitize.
- * @param array|string $patterns A regular expression pattern, or array of
- * regular expression patterns to apply to all values of the target.
- * @param integer $depth The maximum recursive depth to sanitize if the
- * target contains values that are arrays.
- * @param integer $nesting The maximum nesting level in which to dive
- * @return array The sanitized array.
- */
- public static function sanitize(array &$target, array $patterns= array(), $depth= 99, $nesting= 10) {
- foreach ($target as $key => &$value) {
- if (is_array($value) && $depth > 0) {
- modX :: sanitize($value, $patterns, $depth-1);
- } elseif (is_string($value)) {
- if (!empty($patterns)) {
- $iteration = 1;
- $nesting = ((integer) $nesting ? (integer) $nesting : 10);
- while ($iteration <= $nesting) {
- $matched = false;
- foreach ($patterns as $pattern) {
- $patternIterator = 1;
- $patternMatches = preg_match($pattern, $value);
- if ($patternMatches > 0) {
- $matched = true;
- while ($patternMatches > 0 && $patternIterator <= $nesting) {
- $value= preg_replace($pattern, '', $value);
- $patternMatches = preg_match($pattern, $value);
- }
- }
- }
- if (!$matched) {
- break;
- }
- $iteration++;
- }
- }
- if (get_magic_quotes_gpc()) {
- $target[$key]= stripslashes($value);
- } else {
- $target[$key]= $value;
- }
- }
- }
- return $target;
- }
- /**
- * @param array|string $data The target data to sanitize.
- * @param array $replaceable
- * @return array|string The sanitized data
- */
- public static function replaceReserved($data, array $replaceable = array ('[' => '[', ']' => ']', '`' => '`'))
- {
- if (\is_array($data)) {
- $result = array();
- foreach ($data as $key => &$value) {
- $key = self::replaceReserved($key, $replaceable);
- $result[$key] = self::replaceReserved($value, $replaceable);
- }
- } elseif (\is_scalar($data)) {
- $result = \str_replace(\array_keys($replaceable), \array_values($replaceable), $data);
- } else {
- $result = '';
- }
- return $result;
- }
- /**
- * Sanitizes a string
- *
- * @param string $str The string to sanitize
- * @param array $chars An array of chars to remove
- * @param string $allowedTags A list of tags to allow.
- * @return string The sanitized string.
- */
- public function sanitizeString($str,$chars = array('/',"'",'"','(',')',';','>','<'),$allowedTags = '') {
- $str = str_replace($chars,'',strip_tags($str,$allowedTags));
- return preg_replace("/[^A-Za-z0-9_\-\.\/\\p{L}[\p{L} _.-]/u",'',$str);
- }
- /**
- * Turn an associative or numeric array into a valid query string.
- *
- * @static
- * @param array $parameters An associative or numeric-indexed array of parameters.
- * @param string $numPrefix A string prefix added to the numeric-indexed array keys.
- * Ignored if associative array is used.
- * @param string $argSeparator The string used to separate arguments in the resulting query string.
- * @return string A valid query string representing the parameters.
- */
- public static function toQueryString(array $parameters = array(), $numPrefix = '', $argSeparator = '&') {
- return http_build_query($parameters, $numPrefix, $argSeparator);
- }
- /**
- * Create, retrieve, or update specific modX instances.
- *
- * @static
- * @param string|int|null $id An optional identifier for the instance. If not set
- * a uniqid will be generated and used as the key for the instance.
- * @param array|null $config An optional array of config data for the instance.
- * @param bool $forceNew If true a new instance will be created even if an instance
- * with the provided $id already exists in modX::$instances.
- * @return modX An instance of modX.
- * @throws xPDOException
- */
- public static function getInstance($id = null, $config = null, $forceNew = false) {
- $class = __CLASS__;
- if (is_null($id)) {
- if (!is_null($config) || $forceNew || empty(self::$instances)) {
- $id = uniqid($class);
- } else {
- $instances =& self::$instances;
- $id = key($instances);
- }
- }
- if ($forceNew || !array_key_exists($id, self::$instances) || !(self::$instances[$id] instanceof $class)) {
- self::$instances[$id] = new $class('', $config);
- } elseif (self::$instances[$id] instanceof $class && is_array($config)) {
- self::$instances[$id]->config = array_merge(self::$instances[$id]->config, $config);
- }
- if (!(self::$instances[$id] instanceof $class)) {
- throw new xPDOException("Error getting {$class} instance, id = {$id}");
- }
- return self::$instances[$id];
- }
- /**
- * Construct a new modX instance.
- *
- * @param string $configPath An absolute filesystem path to look for the config file.
- * @param array $options xPDO options that can be passed to the instance.
- * @param array $driverOptions PDO driver options that can be passed to the instance.
- * @return modX A new modX instance.
- */
- public function __construct($configPath= '', $options = null, $driverOptions = null) {
- try {
- $options = $this->loadConfig($configPath, $options, $driverOptions);
- parent :: __construct(
- null,
- null,
- null,
- $options,
- null
- );
- $this->setLogLevel($this->getOption('log_level', null, xPDO::LOG_LEVEL_ERROR));
- $this->setLogTarget($this->getOption('log_target', null, 'FILE'));
- $debug = $this->getOption('debug');
- if (!is_null($debug) && $debug !== '') {
- $this->setDebug($debug);
- }
- $this->setPackage('modx', MODX_CORE_PATH . 'model/');
- $this->loadClass('modAccess');
- $this->loadClass('modAccessibleObject');
- $this->loadClass('modAccessibleSimpleObject');
- $this->loadClass('modResource');
- $this->loadClass('modElement');
- $this->loadClass('modScript');
- $this->loadClass('modPrincipal');
- $this->loadClass('modUser');
- $this->loadClass('sources.modMediaSource');
- } catch (xPDOException $xe) {
- $this->sendError('unavailable', array('error_message' => $xe->getMessage()));
- } catch (Exception $e) {
- $this->sendError('unavailable', array('error_message' => $e->getMessage()));
- }
- }
- /**
- * Load the modX configuration when creating an instance of modX.
- *
- * @param string $configPath An absolute path location to search for the modX config file.
- * @param array $data Data provided to initialize the instance with, overriding config file entries.
- * @param null $driverOptions Driver options for the primary connection.
- * @return array The merged config data ready for use by the modX::__construct() method.
- */
- protected function loadConfig($configPath = '', $data = array(), $driverOptions = null) {
- if (!is_array($data)) $data = array();
- modX :: protect();
- if (!defined('MODX_CONFIG_KEY')) {
- define('MODX_CONFIG_KEY', 'config');
- }
- if (empty ($configPath)) {
- $configPath= MODX_CORE_PATH . 'config/';
- }
- global $database_dsn, $database_user, $database_password, $config_options, $driver_options, $table_prefix, $site_id, $uuid;
- if (file_exists($configPath . MODX_CONFIG_KEY . '.inc.php') && include ($configPath . MODX_CONFIG_KEY . '.inc.php')) {
- $cachePath= MODX_CORE_PATH . 'cache/';
- if (MODX_CONFIG_KEY !== 'config') $cachePath .= MODX_CONFIG_KEY . '/';
- if (!is_array($config_options)) $config_options = array();
- if (!is_array($driver_options)) $driver_options = array();
- $data = array_merge(
- array (
- xPDO::OPT_CACHE_KEY => 'default',
- xPDO::OPT_CACHE_HANDLER => 'xPDOFileCache',
- xPDO::OPT_CACHE_PATH => $cachePath,
- xPDO::OPT_TABLE_PREFIX => $table_prefix,
- xPDO::OPT_HYDRATE_FIELDS => true,
- xPDO::OPT_HYDRATE_RELATED_OBJECTS => true,
- xPDO::OPT_HYDRATE_ADHOC_FIELDS => true,
- xPDO::OPT_VALIDATOR_CLASS => 'validation.modValidator',
- xPDO::OPT_VALIDATE_ON_SAVE => true,
- 'cache_system_settings' => true,
- 'cache_system_settings_key' => 'system_settings'
- ),
- $config_options,
- $data
- );
- $primaryConnection = array(
- 'dsn' => $database_dsn,
- 'username' => $database_user,
- 'password' => $database_password,
- 'options' => array(
- xPDO::OPT_CONN_MUTABLE => isset($data[xPDO::OPT_CONN_MUTABLE]) ? (boolean) $data[xPDO::OPT_CONN_MUTABLE] : true,
- ),
- 'driverOptions' => $driver_options
- );
- if (!array_key_exists(xPDO::OPT_CONNECTIONS, $data) || !is_array($data[xPDO::OPT_CONNECTIONS])) {
- $data[xPDO::OPT_CONNECTIONS] = array();
- }
- array_unshift($data[xPDO::OPT_CONNECTIONS], $primaryConnection);
- if (!empty($site_id)) $this->site_id = $site_id;
- if (!empty($uuid)) $this->uuid = $uuid;
- } else {
- throw new xPDOException("Could not load MODX config file.");
- }
- return $data;
- }
- /**
- * Initializes the modX engine.
- *
- * This includes preparing the session, pre-loading some common
- * classes and objects, the current site and context settings, extension
- * packages used to override session handling, error handling, or other
- * initialization classes
- *
- * @param string $contextKey Indicates the context to initialize.
- * @param array|null $options An array of options for the initialization.
- * @return bool True if initialized successfully, or already initialized.
- */
- public function initialize($contextKey= 'web', $options = null) {
- if (!$this->_initialized) {
- if (!$this->startTime) {
- $this->startTime= microtime(true);
- }
- $this->getCacheManager();
- $this->getConfig();
- $this->_initContext($contextKey, false, $options);
- $this->_loadExtensionPackages($options);
- $this->_initSession($options);
- $this->_initErrorHandler($options);
- $this->_initCulture($options);
- $this->getService('registry', 'registry.modRegistry');
- $this->invokeEvent(
- 'OnMODXInit',
- array(
- 'contextKey' => $contextKey,
- 'options' => $options
- )
- );
- if (is_array ($this->config)) {
- $this->setPlaceholders($this->config, '+');
- }
- $this->_initialized= true;
- }
- return $this->_initialized;
- }
- /**
- * Loads any extension packages.
- *
- * @param array|null An optional array of options that can contain additional
- * extension packages which will be merged with those specified via config.
- */
- protected function _loadExtensionPackages($options = null) {
- $cache = $this->call('modExtensionPackage','loadCache',array(&$this));
- if (!empty($cache)) {
- foreach ($cache as $package) {
- $package['table_prefix'] = isset($package['table_prefix']) ? $package['table_prefix'] : null;
- $this->addPackage($package['namespace'],$package['path'],$package['table_prefix']);
- if (!empty($package['service_name']) && !empty($package['service_class'])) {
- $this->getService($package['service_name'],$package['service_class'],$package['path']);
- }
- }
- }
- $this->_loadExtensionPackagesDeprecated($options);
- }
- /**
- * Load system-setting based extension packages. This is not recommended; use modExtensionPackage from 2.3 onward.
- * The System Setting will be automatically removed in 2.4/3.0 and no longer functional.
- *
- * @deprecated To be removed in 2.4/3.0
- * @param null $options
- */
- protected function _loadExtensionPackagesDeprecated($options = null) {
- $extPackages = $this->getOption('extension_packages');
- $extPackages = $this->fromJSON($extPackages);
- if (!is_array($extPackages)) $extPackages = array();
- if (is_array($options) && array_key_exists('extension_packages', $options)) {
- $optPackages = $this->fromJSON($options['extension_packages']);
- if (is_array($optPackages)) {
- $extPackages = array_merge($extPackages, $optPackages);
- }
- }
- if (!empty($extPackages)) {
- foreach ($extPackages as $extPackage) {
- if (!is_array($extPackage)) continue;
- foreach ($extPackage as $packageName => $package) {
- if (!empty($package) && !empty($package['path'])) {
- $package['tablePrefix'] = isset($package['tablePrefix']) ? $package['tablePrefix'] : null;
- $package['path'] = str_replace(array(
- '[[++core_path]]',
- '[[++base_path]]',
- '[[++assets_path]]',
- '[[++manager_path]]',
- ),array(
- $this->config['core_path'],
- $this->config['base_path'],
- $this->config['assets_path'],
- $this->config['manager_path'],
- ),$package['path']);
- $this->addPackage($packageName,$package['path'],$package['tablePrefix']);
- if (!empty($package['serviceName']) && !empty($package['serviceClass'])) {
- $packagePath = str_replace('//','/',$package['path'].$packageName.'/');
- $this->getService($package['serviceName'],$package['serviceClass'],$packagePath);
- }
- }
- }
- }
- }
- }
- /**
- * Sets the debugging features of the modX instance.
- *
- * @param boolean|int $debug Boolean or bitwise integer describing the
- * debug state and/or PHP error reporting level.
- * @param boolean $stopOnNotice Indicates if processing should stop when
- * encountering PHP errors of type E_NOTICE.
- * @return boolean|int The previous value.
- *
- * @info PHP errors are handle by modErrorHandler with at most LOG_LEVEL_INFO
- * When called by modX $debug is a string (ie $this->getOption('debug'))
- *
- * (bool)true , (string)true , (string)-1 -> LOG_LEVEL_DEBUG (MODX), E_ALL | E_STRICT (PHP)
- * (bool)false, (string)false, (string) 0 -> LOG_LEVEL_ERROR (MODX), 0 (PHP)
- * (int)nnn -> LOG_LEVEL_INFO (MODX), nnn (PHP)
- * (string)E_XXX -> LOG_LEVEL_INFO (MODX), E_XXX (PHP)
- */
- public function setDebug($debug= true) {
- $oldValue= $this->getDebug();
- if (($debug === true) || ('true' === $debug) || ('-1' === $debug)) {
- error_reporting(-1);
- parent :: setDebug(true);
- }
- else {
- if (($debug === false) || ('false' === $debug) || ('0' === $debug)) {
- error_reporting(0);
- parent :: setDebug(false);
- }
- else {
- $debug = (is_int($debug) ? $debug : defined($debug) ? intval(constant($debug)) : 0);
- if ($debug) {
- error_reporting($debug);
- parent :: setLogLevel(xPDO::LOG_LEVEL_INFO);
- }
- }
- }
- return $oldValue;
- }
- /**
- * Get an extended xPDOCacheManager instance responsible for MODX caching.
- *
- * @param string $class The class name of the cache manager to load
- * @param array $options An array of options to send to the cache manager instance
- * @return modCacheManager A modCacheManager instance registered for this modX instance.
- */
- public function getCacheManager($class= 'cache.xPDOCacheManager', $options = array('path' => XPDO_CORE_PATH, 'ignorePkg' => true)) {
- if ($this->cacheManager === null) {
- if ($this->loadClass($class, $options['path'], $options['ignorePkg'], true)) {
- $cacheManagerClass= $this->getOption('modCacheManager.class', null, 'modCacheManager');
- if ($className= $this->loadClass($cacheManagerClass, '', false, true)) {
- if ($this->cacheManager= new $className ($this)) {
- $this->_cacheEnabled= true;
- }
- }
- }
- }
- return $this->cacheManager;
- }
- /**
- * Gets the MODX parser.
- *
- * Returns an instance of modParser responsible for parsing tags in element
- * content, performing actions, returning content and/or sending other responses
- * in the process.
- *
- * @return modParser The modParser for this modX instance.
- */
- public function getParser() {
- return $this->getService('parser', $this->getOption('parser_class', null, 'modParser'), $this->getOption('parser_class_path', null, ''));
- }
- /**
- * Gets all of the parent resource ids for a given resource.
- *
- * @param integer $id The resource id for the starting node.
- * @param integer $height How many levels max to search for parents (default 10).
- * @param array $options An array of filtering options, such as 'context' to specify the context to grab from
- * @return array An array of all the parent resource ids for the specified resource.
- */
- public function getParentIds($id= null, $height= 10,array $options = array()) {
- $parentId= 0;
- $parents= array ();
- if ($id && $height > 0) {
- $context = '';
- if (!empty($options['context'])) {
- $this->getContext($options['context']);
- $context = $options['context'];
- }
- $resourceMap = !empty($context) && !empty($this->contexts[$context]->resourceMap) ? $this->contexts[$context]->resourceMap : $this->resourceMap;
- foreach ($resourceMap as $parentId => $mapNode) {
- if (array_search($id, $mapNode) !== false) {
- $parents[]= $parentId;
- break;
- }
- }
- if ($parentId && !empty($parents)) {
- $height--;
- $parents= array_merge($parents, $this->getParentIds($parentId,$height,$options));
- }
- }
- return $parents;
- }
- /**
- * Gets all of the child resource ids for a given resource.
- *
- * @see getTree for hierarchical node results
- * @param integer $id The resource id for the starting node.
- * @param integer $depth How many levels max to search for children (default 10).
- * @param array $options An array of filtering options, such as 'context' to specify the context to grab from
- * @return array An array of all the child resource ids for the specified resource.
- */
- public function getChildIds($id= null, $depth= 10,array $options = array()) {
- $children= array ();
- if ($id !== null && intval($depth) >= 1) {
- $id= is_int($id) ? $id : intval($id);
- $context = '';
- if (!empty($options['context'])) {
- $this->getContext($options['context']);
- $context = $options['context'];
- }
- $resourceMap = !empty($context) && !empty($this->contexts[$context]->resourceMap) ? $this->contexts[$context]->resourceMap : $this->resourceMap;
- if (isset ($resourceMap["{$id}"])) {
- if ($children= $resourceMap["{$id}"]) {
- foreach ($children as $child) {
- if ($c = $this->getChildIds($child, $depth - 1, $options)) {
- $children = array_merge($children, $c);
- }
- }
- }
- }
- }
- return $children;
- }
- /**
- * Get a site tree from a single or multiple modResource instances.
- *
- * @see getChildIds for linear results
- * @param int|array $id A single or multiple modResource ids to build the
- * tree from.
- * @param int $depth The maximum depth to build the tree (default 10).
- * @param array $options An array of filtering options, such as 'context' to specify the context to grab from
- * @return array An array containing the tree structure.
- */
- public function getTree($id= null, $depth= 10, array $options = array()) {
- $tree= array ();
- if (!empty($options['context'])) {
- $this->getContext($options['context']);
- }
- if ($id !== null) {
- if (is_array ($id)) {
- foreach ($id as $k => $v) {
- $tree[$v] = $this->getTree($v, $depth - 1, $options);
- }
- } elseif ($branch= $this->getChildIds($id, 1, $options)) {
- foreach ($branch as $key => $child) {
- if ($depth > 0 && $leaf = $this->getTree($child, $depth - 1, $options)) {
- $tree[$child]= $leaf;
- } else {
- $tree[$child]= $child;
- }
- }
- }
- }
- return $tree;
- }
- /**
- * Sets a placeholder value.
- *
- * @param string $key The unique string key which identifies the
- * placeholder.
- * @param mixed $value The value to set the placeholder to.
- */
- public function setPlaceholder($key, $value) {
- if (is_string($key)) {
- $this->placeholders["{$key}"]= $value;
- }
- }
- /**
- * Sets a collection of placeholders stored in an array or as object vars.
- *
- * An optional namespace parameter can be prepended to each placeholder key in the collection,
- * to isolate the collection of placeholders.
- *
- * Note that unlike toPlaceholders(), this function does not add separators between the
- * namespace and the placeholder key. Use toPlaceholders() when working with multi-dimensional
- * arrays or objects with variables other than scalars so each level gets delimited by a
- * separator.
- *
- * @param array|object $placeholders An array of values or object to set as placeholders.
- * @param string $namespace A namespace prefix to prepend to each placeholder key.
- */
- public function setPlaceholders($placeholders, $namespace= '') {
- $this->toPlaceholders($placeholders, $namespace, '');
- }
- /**
- * Sets placeholders from values stored in arrays and objects.
- *
- * Each recursive level adds to the prefix, building an access path using an optional separator.
- *
- * @param array|object $subject An array or object to process.
- * @param string $prefix An optional prefix to be prepended to the placeholder keys. Recursive
- * calls prepend the parent keys.
- * @param string $separator A separator to place in between the prefixes and keys. Default is a
- * dot or period: '.'.
- * @param boolean $restore Set to true if you want overwritten placeholder values returned.
- * @return array A multi-dimensional array containing up to two elements: 'keys' which always
- * contains an array of placeholder keys that were set, and optionally, if the restore parameter
- * is true, 'restore' containing an array of placeholder values that were overwritten by the method.
- */
- public function toPlaceholders($subject, $prefix= '', $separator= '.', $restore= false) {
- $keys = array();
- $restored = array();
- if (is_object($subject)) {
- if ($subject instanceof xPDOObject) {
- $subject= $subject->toArray();
- } else {
- $subject= get_object_vars($subject);
- }
- }
- if (is_array($subject)) {
- foreach ($subject as $key => $value) {
- $rv = $this->toPlaceholder($key, $value, $prefix, $separator, $restore);
- if (isset($rv['keys'])) {
- foreach ($rv['keys'] as $rvKey) $keys[] = $rvKey;
- }
- if ($restore === true && isset($rv['restore'])) {
- $restored = array_merge($restored, $rv['restore']);
- }
- }
- }
- $return = array('keys' => $keys);
- if ($restore === true) $return['restore'] = $restored;
- return $return;
- }
- /**
- * Recursively validates and sets placeholders appropriate to the value type passed.
- *
- * @param string $key The key identifying the value.
- * @param mixed $value The value to set.
- * @param string $prefix A string prefix to prepend to the key. Recursive calls prepend the
- * parent keys as well.
- * @param string $separator A separator placed in between the prefix and the key. Default is a
- * dot or period: '.'.
- * @param boolean $restore Set to true if you want overwritten placeholder values returned.
- * @return array A multi-dimensional array containing up to two elements: 'keys' which always
- * contains an array of placeholder keys that were set, and optionally, if the restore parameter
- * is true, 'restore' containing an array of placeholder values that were overwritten by the method.
- */
- public function toPlaceholder($key, $value, $prefix= '', $separator= '.', $restore= false) {
- $return = array('keys' => array());
- if ($restore === true) $return['restore'] = array();
- if (!empty($prefix) && !empty($separator)) {
- $prefix .= $separator;
- }
- if (is_array($value) || is_object($value)) {
- $return = $this->toPlaceholders($value, "{$prefix}{$key}", $separator, $restore);
- } elseif (is_scalar($value)) {
- $return['keys'][] = "{$prefix}{$key}";
- if ($restore === true && array_key_exists("{$prefix}{$key}", $this->placeholders)) {
- $return['restore']["{$prefix}{$key}"] = $this->getPlaceholder("{$prefix}{$key}");
- }
- $this->setPlaceholder("{$prefix}{$key}", $value);
- }
- return $return;
- }
- /**
- * Get a placeholder value by key.
- *
- * @param string $key The key of the placeholder to a return a value from.
- * @return mixed The value of the requested placeholder, or an empty string if not located.
- */
- public function getPlaceholder($key) {
- $placeholder= null;
- if (is_string($key) && array_key_exists($key, $this->placeholders)) {
- $placeholder= & $this->placeholders["{$key}"];
- }
- return $placeholder;
- }
- /**
- * Unset a placeholder value by key.
- *
- * @param string $key The key of the placeholder to unset.
- */
- public function unsetPlaceholder($key) {
- if (is_string($key) && array_key_exists($key, $this->placeholders)) {
- unset($this->placeholders[$key]);
- }
- }
- /**
- * Unset multiple placeholders, either by prefix or an array of keys.
- *
- * @param string|array $keys A string prefix or an array of keys indicating
- * the placeholders to unset.
- */
- public function unsetPlaceholders($keys) {
- if (is_array($keys)) {
- foreach ($keys as $key) {
- if (is_string($key)) $this->unsetPlaceholder($key);
- if (is_array($key)) $this->unsetPlaceholders($key);
- }
- } elseif (is_string($keys)) {
- $placeholderKeys = array_keys($this->placeholders);
- foreach ($placeholderKeys as $key) {
- if (strpos($key, $keys) === 0) $this->unsetPlaceholder($key);
- }
- }
- }
- /**
- * Returns the full table name (with dynamic prefix) based on database settings.
- * Legacy - Useful when dealing with migrations or prefixed database tables without an xPDO model (which xPDO.getTableName requires.)
- *
- * @param string $table Name of MODX table, less table prefix.
- * @return string Full table name containing database and table prefix.
- */
- public function getFullTableName( $table = '' ) {
- return $this->getOption('dbname') .".". $this->getOption( xPDO::OPT_TABLE_PREFIX ) . $table;
- }
- /**
- * Generates a URL representing a specified resource.
- *
- * @param integer $id The id of a resource.
- * @param string $context Specifies a context to limit URL generation to.
- * @param string $args A query string to append to the generated URL.
- * @param mixed $scheme The scheme indicates in what format the URL is generated.<br>
- * <pre>
- * -1 : (default value) URL is relative to site_url
- * 0 : see http
- * 1 : see https
- * full : URL is absolute, prepended with site_url from config
- * abs : URL is absolute, prepended with base_url from config
- * http : URL is absolute, forced to http scheme
- * https : URL is absolute, forced to https scheme
- * </pre>
- * @param array $options An array of options for generating the Resource URL.
- * @return string The URL for the resource.
- */
- public function makeUrl($id, $context= '', $args= '', $scheme= -1, array $options= array()) {
- $url= '';
- if ($validid = intval($id)) {
- $id = $validid;
- if ($context == '' || $this->context->get('key') == $context) {
- $url= $this->context->makeUrl($id, $args, $scheme, $options);
- }
- if (empty($url) && ($context !== $this->context->get('key'))) {
- $ctx= null;
- if ($context == '') {
- /** @var PDOStatement $stmt */
- if ($stmt = $this->prepare("SELECT context_key FROM " . $this->getTableName('modResource') . " WHERE id = :id")) {
- $stmt->bindValue(':id', $id);
- if ($contextKey = $this->getValue($stmt)) {
- $ctx = $this->getContext($contextKey);
- }
- }
- } else {
- $ctx = $this->getContext($context);
- }
- if ($ctx) {
- $url= $ctx->makeUrl($id, $args, 'full', $options);
- }
- }
- if (!empty($url) && $this->getOption('xhtml_urls', $options, false)) {
- $url= preg_replace("/&(?!amp;)/","&", $url);
- }
- } else {
- $this->log(modX::LOG_LEVEL_ERROR, '`' . $id . '` is not a valid integer and may not be passed to makeUrl()');
- }
- return $url;
- }
- /**
- * Filter a string for use as a URL path segment.
- *
- * @param string $string The string to filter into a valid path segment.
- * @param array $options Optional filter setting overrides.
- *
- * @return string|null A valid path segment string or null if an error occurs.
- */
- public function filterPathSegment($string, array $options = array()) {
- return $this->call('modResource', 'filterPathSegment', array(&$this, $string, $options));
- }
- public function findResource($uri, $context = '') {
- $resourceId = false;
- if (empty($context) && isset($this->context)) $context = $this->context->get('key');
- if (!empty($context) && (!empty($uri) || $uri === '0')) {
- $useAliasMap = (boolean) $this->getOption('cache_alias_map', null, false);
- if ($useAliasMap) {
- if (isset($this->context) && $this->context->get('key') === $context && is_array($this->aliasMap) && array_key_exists($uri, $this->aliasMap)) {
- $resourceId = (integer) $this->aliasMap[$uri];
- } elseif ($ctx = $this->getContext($context)) {
- $useAliasMap = $ctx->getOption('cache_alias_map', false) && is_array($ctx->aliasMap) && array_key_exists($uri, $ctx->aliasMap);
- if ($useAliasMap && array_key_exists($uri, $ctx->aliasMap)) {
- $resourceId = (integer) $ctx->aliasMap[$uri];
- }
- }
- }
- if (!$resourceId && !$useAliasMap) {
- $query = $this->newQuery('modResource', array('context_key' => $context, 'uri' => $uri, 'deleted' => false));
- $query->select($this->getSelectColumns('modResource', '', '', array('id')));
- $stmt = $query->prepare();
- if ($stmt) {
- $value = $this->getValue($stmt);
- if ($value) {
- $resourceId = $value;
- }
- }
- }
- }
- return $resourceId;
- }
- /**
- * Send the user to a type-specific core error page and halt PHP execution.
- *
- * @param string $type The type of error to present.
- * @param array $options An array of options to provide for the error file.
- */
- public function sendError($type = '', $options = array()) {
- if (!is_string($type) || empty($type)) $type = $this->getOption('error_type', $options, 'unavailable');
- while (ob_get_level() && @ob_end_clean()) {}
- if (!XPDO_CLI_MODE) {
- $errorPageTitle = $this->getOption('error_pagetitle', $options, 'Error 503: Service temporarily unavailable');
- $errorMessage = $this->getOption('error_message', $options, '<p>Site temporarily unavailable.</p>');
- $errorHeader = $this->getOption('error_header', $options, $_SERVER['SERVER_PROTOCOL'] . ' 503 Service Unavailable');
- if (file_exists(MODX_CORE_PATH . "error/{$type}.include.php")) {
- @include(MODX_CORE_PATH . "error/{$type}.include.php");
- }
- header($errorHeader);
- echo "<html><head><title>{$errorPageTitle}</title></head><body>{$errorMessage}</body></html>";
- @session_write_close();
- } else {
- echo ucfirst($type) . "\n";
- echo $this->getOption('error_message', $options, 'Service temporarily unavailable') . "\n";
- }
- exit();
- }
- /**
- * Sends a redirect to the specified URL using the specified options.
- *
- * Valid 'type' option values include:
- * REDIRECT_REFRESH Uses the header refresh method
- * REDIRECT_META Sends a a META HTTP-EQUIV="Refresh" tag to the output
- * REDIRECT_HEADER Uses the header location method
- *
- * REDIRECT_HEADER is the default.
- *
- * @param string $url The URL to redirect the client browser to.
- * @param array|boolean $options An array of options for the redirect OR
- * indicates if redirect attempts should be counted and limited to 3 (latter is deprecated
- * usage; use count_attempts in options array).
- * @param string $type The type of redirection to attempt (deprecated, use type in
- * options array).
- * @param string $responseCode The type of HTTP response code HEADER to send for the
- * redirect (deprecated, use responseCode in options array)
- */
- public function sendRedirect($url, $options= false, $type= '', $responseCode = '') {
- if (!$this->getResponse()) {
- $this->log(modX::LOG_LEVEL_FATAL, "Could not load response class.");
- }
- if (!is_array($options)) {
- $options = array('count_attempts' => (boolean) $options);
- }
- if ($type) {
- $this->deprecated('2.0.5', 'Use type in options array instead.', 'sendRedirect method parameter $type');
- $options['type'] = $type;
- $type = '';
- }
- if ($responseCode) {
- $this->deprecated('2.0.5', 'Use responseCode in options array instead.', 'sendRedirect method parameter $responseCode');
- $options['responseCode'] = $responseCode;
- $responseCode = '';
- }
- $this->response->sendRedirect($url, $options, $type, $responseCode);
- }
- /**
- * Forwards the request to another resource without changing the URL.
- *
- * @param integer $id The resource identifier.
- * @param string $options An array of options for the process.
- * @param boolean $sendErrorPage Whether we should skip the sendErrorPage if the resource does not exist.
- */
- public function sendForward($id, $options = null, $sendErrorPage = true) {
- if (!$this->getRequest()) {
- $this->log(modX::LOG_LEVEL_FATAL, "Could not load request class.");
- }
- $idInt = intval($id);
- if (is_string($options) && !empty($options)) {
- $options = array('response_code' => $options);
- } elseif (!is_array($options)) {
- $options = array();
- }
- $this->elementCache = array();
- if ($idInt > 0) {
- $merge = array_key_exists('merge', $options) && !empty($options['merge']);
- $currentResource = array();
- if ($merge) {
- $excludes = array_merge(
- explode(',', $this->getOption('forward_merge_excludes', $options, 'type,published,class_key')),
- array(
- 'content'
- ,'pub_date'
- ,'unpub_date'
- ,'richtext'
- ,'_content'
- ,'_processed'
- )
- );
- if (!empty($this->resource->_fields)) {
- foreach ($this->resource->_fields as $fkey => $fval) {
- if (!in_array($fkey, $excludes)) {
- if (is_scalar($fval) && $fval !== '') {
- $currentResource[$fkey] = $fval;
- } elseif (is_array($fval) && count($fval) === 5 && $fval[1] !== '') {
- $currentResource[$fkey] = $fval;
- }
- }
- }
- }
- }
- $this->resource= $this->request->getResource('id', $idInt, array('forward' => true));
- if ($this->resource) {
- if ($merge && !empty($currentResource)) {
- $this->resource->_fields = array_merge($this->resource->_fields, $currentResource);
- $this->elementCache = array();
- unset($currentResource);
- }
- $this->resourceIdentifier= $this->resource->get('id');
- $this->resourceMethod= 'id';
- if (isset($options['response_code']) && !empty($options['response_code'])) {
- header($options['response_code']);
- }
- $this->request->prepareResponse();
- exit();
- } elseif ($sendErrorPage) {
- $this->sendErrorPage();
- }
- $options= array_merge(
- array(
- 'error_type' => '404'
- ,'error_header' => $this->getOption('error_page_header', $options,$_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found')
- ,'error_pagetitle' => $this->getOption('error_page_pagetitle', $options,'Error 404: Page not found')
- ,'error_message' => $this->getOption('error_page_message', $options,'<h1>Page not found</h1><p>The page you requested was not found.</p>')
- ),
- $options
- );
- }
- $this->sendError($id, $options);
- }
- /**
- * Send the user to a MODX virtual error page.
- *
- * @uses invokeEvent() The OnPageNotFound event is invoked before the error page is forwarded
- * to.
- * @param array $options An array of options to provide for the OnPageNotFound event and error
- * page.
- */
- public function sendErrorPage($options = null) {
- if (!is_array($options)) $options = array();
- $options= array_merge(
- array(
- 'response_code' => $this->getOption('error_page_header', $options, $_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found')
- ,'error_type' => '404'
- ,'error_header' => $this->getOption('error_page_header', $options, $_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found')
- ,'error_pagetitle' => $this->getOption('error_page_pagetitle', $options, 'Error 404: Page not found')
- ,'error_message' => $this->getOption('error_page_message', $options, '<h1>Page not found</h1><p>The page you requested was not found.</p>')
- ),
- $options
- );
- $this->invokeEvent('OnPageNotFound', $options);
- $this->sendForward($this->getOption('error_page', $options, $this->getOption('site_start')), $options, false);
- }
- /**
- * Send the user to the MODX unauthorized page.
- *
- * @uses invokeEvent() The OnPageUnauthorized event is invoked before the unauthorized page is
- * forwarded to.
- * @param array $options An array of options to provide for the OnPageUnauthorized
- * event and unauthorized page.
- */
- public function sendUnauthorizedPage($options = null) {
- if (!is_array($options)) $options = array();
- $options= array_merge(
- array(
- 'response_code' => $this->getOption('unauthorized_page_header' ,$options ,$_SERVER['SERVER_PROTOCOL'] . ' 401 Unauthorized')
- ,'error_type' => '401'
- ,'error_header' => $this->getOption('unauthorized_page_header', $options,$_SERVER['SERVER_PROTOCOL'] . ' 401 Unauthorized')
- ,'error_pagetitle' => $this->getOption('unauthorized_page_pagetitle',$options, 'Error 401: Unauthorized')
- ,'error_message' => $this->getOption('unauthorized_page_message', $options,'<h1>Unauthorized</h1><p>You are not authorized to view the requested content.</p>')
- ),
- $options
- );
- $this->invokeEvent('OnPageUnauthorized', $options);
- $this->sendForward($this->getOption('unauthorized_page', $options, $this->getOption('site_start')), $options);
- }
- /**
- * Get the current authenticated User and assign it to the modX instance.
- *
- * @param string $contextKey An optional context to get the user from.
- * @param boolean $forceLoadSettings If set to true, will load settings
- * regardless of whether the user has an authenticated context or not.
- * @return modUser The user object authenticated for the request.
- */
- public function getUser($contextKey= '',$forceLoadSettings = false) {
- if ($contextKey == '') {
- if ($this->context !== null) {
- $contextKey= $this->context->get('key');
- }
- }
- if ($this->user === null || !is_object($this->user)) {
- $this->user= $this->getAuthenticatedUser($contextKey);
- if ($contextKey !== 'mgr' && !$this->user) {
- $this->user= $this->getAuthenticatedUser('mgr');
- }
- }
- if ($this->user !== null && is_object($this->user)) {
- if ($this->user->hasSessionContext($contextKey) || $forceLoadSettings) {
- if (!$forceLoadSettings && isset ($_SESSION["modx.{$contextKey}.user.config"])) {
- $this->_userConfig= $_SESSION["modx.{$contextKey}.user.config"];
- } else {
- $this->_userConfig= array();
- $settings= $this->user->getSettings();
- if (is_array($settings) && !empty ($settings)) {
- foreach ($settings as $k => $v) {
- $matches= array();
- if (preg_match_all('~\{(.*?)\}~', $v, $matches, PREG_SET_ORDER)) {
- foreach ($matches as $match) {
- if (isset($this->_userConfig["{$match[1]}"])) {
- $matchValue= $this->_userConfig["{$match[1]}"];
- } elseif (isset($this->config["{$match[1]}"])) {
- $matchValue= $this->config["{$match[1]}"];
- } else {
- $matchValue= '';
- }
- $v= str_replace($match[0], $matchValue, $v);
- }
- }
- $this->_userConfig[$k]= $v;
- }
- }
- $_SESSION["modx.{$contextKey}.user.config"]= $this->_userConfig;
- }
- if (is_array($this->_userConfig) && !empty($this->_userConfig)) {
- $this->config= array_merge($this->config, $this->_userConfig);
- }
- }
- } else {
- $this->user = $this->newObject('modUser');
- $this->user->fromArray(array(
- 'id' => 0,
- 'username' => $this->getOption('default_username','','(anonymous)',true)
- ), '', true);
- }
- ksort($this->config);
- $this->toPlaceholders($this->user->get(array('id','username')),'modx.user');
- return $this->user;
- }
- /**
- * Gets the user authenticated in the specified context.
- *
- * @param string $contextKey Optional context key; uses current context by default.
- * @return modUser|null The user object that is authenticated in the specified context,
- * or null if no user is authenticated.
- */
- public function getAuthenticatedUser($contextKey= '') {
- $user= null;
- if ($contextKey == '') {
- if ($this->context !== null) {
- $contextKey= $this->context->get('key');
- }
- }
- if ($contextKey && isset ($_SESSION['modx.user.contextTokens'][$contextKey])) {
- $user= $this->getObject('modUser', intval($_SESSION['modx.user.contextTokens'][$contextKey]), true);
- if ($user) {
- $user->getSessionContexts();
- }
- }
- return $user;
- }
- /**
- * Checks to see if the user has a session in the specified context.
- *
- * @param string $sessionContext The context to test for a session key in.
- * @return boolean True if the user is valid in the context specified.
- */
- public function checkSession($sessionContext= 'web') {
- $hasSession = false;
- if ($this->user !== null) {
- $hasSession = $this->user->hasSessionContext($sessionContext);
- }
- return $hasSession;
- }
- /**
- * Gets the modX core version data.
- *
- * @return array The version data loaded from the config version file.
- */
- public function getVersionData() {
- if ($this->version === null) {
- $this->version= @ include_once MODX_CORE_PATH . "docs/version.inc.php";
- }
- return $this->version;
- }
- /**
- * Reload the config settings.
- *
- * @return array An associative array of configuration key/values
- */
- public function reloadConfig() {
- $this->getCacheManager();
- $this->cacheManager->refresh();
- if (!$this->_loadConfig()) {
- $this->log(modX::LOG_LEVEL_ERROR, 'Could not reload core MODX configuration!');
- }
- return $this->config;
- }
- /**
- * Get the configuration for the site.
- *
- * @return array An associate array of configuration key/values
- */
- public function getConfig() {
- if (!$this->_initialized || !is_array($this->config) || empty ($this->config)) {
- if (!isset ($this->config['base_url']))
- $this->config['base_url']= MODX_BASE_URL;
- if (!isset ($this->config['base_path']))
- $this->config['base_path']= MODX_BASE_PATH;
- if (!isset ($this->config['core_path']))
- $this->config['core_path']= MODX_CORE_PATH;
- if (!isset ($this->config['url_scheme']))
- $this->config['url_scheme']= MODX_URL_SCHEME;
- if (!isset ($this->config['http_host']))
- $this->config['http_host']= MODX_HTTP_HOST;
- if (!isset ($this->config['site_url']))
- $this->config['site_url']= MODX_SITE_URL;
- if (!isset ($this->config['manager_path']))
- $this->config['manager_path']= MODX_MANAGER_PATH;
- if (!isset ($this->config['manager_url']))
- $this->config['manager_url']= MODX_MANAGER_URL;
- if (!isset ($this->config['assets_path']))
- $this->config['assets_path']= MODX_ASSETS_PATH;
- if (!isset ($this->config['assets_url']))
- $this->config['assets_url']= MODX_ASSETS_URL;
- if (!isset ($this->config['connectors_path']))
- $this->config['connectors_path']= MODX_CONNECTORS_PATH;
- if (!isset ($this->config['connectors_url']))
- $this->config['connectors_url']= MODX_CONNECTORS_URL;
- if (!isset ($this->config['connector_url']))
- $this->config['connector_url']= MODX_CONNECTORS_URL . 'index.php';
- if (!isset ($this->config['processors_path']))
- $this->config['processors_path']= MODX_PROCESSORS_PATH;
- if (!isset ($this->config['request_param_id']))
- $this->config['request_param_id']= 'id';
- if (!isset ($this->config['request_param_alias']))
- $this->config['request_param_alias']= 'q';
- if (!isset ($this->config['https_port']))
- $this->config['https_port']= isset($GLOBALS['https_port']) ? $GLOBALS['https_port'] : 443;
- if (!isset ($this->config['error_handler_class']))
- $this->config['error_handler_class']= 'error.modErrorHandler';
- if (!isset ($this->config['server_port']))
- $this->config['server_port']= isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : '';
- $this->_config= $this->config;
- if (!$this->_loadConfig()) {
- $this->log(modX::LOG_LEVEL_FATAL, "Could not load core MODX configuration!");
- return null;
- }
- }
- return $this->config;
- }
- /**
- * Initialize, cleanse, and process a request made to a modX site.
- *
- * @return mixed The result of the request handler.
- */
- public function handleRequest() {
- if ($this->getRequest()) {
- return $this->request->handleRequest();
- }
- return '';
- }
- /**
- * Attempt to load the request handler class, if not already loaded.
- *
- * @access public
- * @param string $class The class name of the response class to load. Defaults to
- * modRequest; is ignored if the Setting "modRequest.class" is set.
- * @param string $path The absolute path by which to load the response class from.
- * Defaults to the current MODX model path.
- * @return boolean Returns true if a valid request handler object was
- * loaded on this or any previous call to the function, false otherwise.
- */
- public function getRequest($class= 'modRequest', $path= '') {
- if ($this->request === null || !($this->request instanceof modRequest)) {
- $requestClass = $this->getOption('modRequest.class',$this->config,$class);
- if ($requestClass !== $class) {
- $this->loadClass('modRequest', '', false, true);
- }
- if ($className= $this->loadClass($requestClass, $path, !empty($path), true))
- $this->request= new $className ($this);
- }
- return is_object($this->request) && $this->request instanceof modRequest;
- }
- /**
- * Attempt to load the response handler class, if not already loaded.
- *
- * @access public
- * @param string $class The class name of the response class to load. Defaults to
- * modResponse; is ignored if the Setting "modResponse.class" is set.
- * @param string $path The absolute path by which to load the response class from.
- * Defaults to the current MODX model path.
- * @return boolean Returns true if a valid response handler object was
- * loaded on this or any previous call to the function, false otherwise.
- */
- public function getResponse($class= 'modResponse', $path= '') {
- $responseClass= $this->getOption('modResponse.class',$this->config,$class);
- $className= $this->loadClass($responseClass, $path, !empty($path), true);
- if ($this->response === null || !($this->response instanceof $className)) {
- if ($className) $this->response= new $className ($this);
- }
- return $this->response instanceof $className;
- }
- /**
- * Register CSS to be injected inside the HEAD tag of a resource.
- *
- * @param string $src The CSS to be injected before the closing HEAD tag in
- * an HTML response.
- * @param string $media all, aural, braille, embossed, handheld, print, projection, screen, tty, tv
- * @return void
- */
- public function regClientCSS($src, $media = null) {
- if (isset ($this->loadedjscripts[$src]) && $this->loadedjscripts[$src]) {
- return;
- }
- $this->loadedjscripts[$src]= true;
- if (strpos(strtolower($src), "<style") !== false || strpos(strtolower($src), "<link") !== false) {
- $this->sjscripts[count($this->sjscripts)]= $src;
- } else {
- if (!empty($media)) {
- $media = ' media="' . $media .'"';
- }
- $this->sjscripts[count($this->sjscripts)]= '<link rel="stylesheet" href="' . $src . '" type="text/css"' . $media . ' />';
- }
- }
- /**
- * Register JavaScript to be injected inside the HEAD tag of a resource.
- *
- * @param string $src The JavaScript to be injected before the closing HEAD
- * tag of an HTML response.
- * @param boolean $plaintext Optional param to treat the $src as plaintext
- * rather than assuming it is JavaScript.
- * @return void
- */
- public function regClientStartupScript($src, $plaintext= false) {
- if (!empty ($src) && !array_key_exists($src, $this->loadedjscripts)) {
- if (isset ($this->loadedjscripts[$src]))
- return;
- $this->loadedjscripts[$src]= true;
- if ($plaintext == true) {
- $this->sjscripts[count($this->sjscripts)]= $src;
- } elseif (strpos(strtolower($src), "<script") !== false) {
- $this->sjscripts[count($this->sjscripts)]= $src;
- } else {
- $this->sjscripts[count($this->sjscripts)]= '<script type="text/javascript" src="' . $src . '"></script>';
- }
- }
- }
- /**
- * Register JavaScript to be injected before the closing BODY tag.
- *
- * @param string $src The JavaScript to be injected before the closing BODY
- * tag in an HTML response.
- * @param boolean $plaintext Optional param to treat the $src as plaintext
- * rather than assuming it is JavaScript.
- * @return void
- */
- public function regClientScript($src, $plaintext= false) {
- if (isset ($this->loadedjscripts[$src]))
- return;
- $this->loadedjscripts[$src]= true;
- if ($plaintext == true) {
- $this->jscripts[count($this->jscripts)]= $src;
- } elseif (strpos(strtolower($src), "<script") !== false) {
- $this->jscripts[count($this->jscripts)]= $src;
- } else {
- $this->jscripts[count($this->jscripts)]= '<script type="text/javascript" src="' . $src . '"></script>';
- }
- }
- /**
- * Register HTML to be injected before the closing HEAD tag.
- *
- * @param string $html The HTML to be injected.
- */
- public function regClientStartupHTMLBlock($html) {
- return $this->regClientStartupScript($html, true);
- }
- /**
- * Register HTML to be injected before the closing BODY tag.
- *
- * @param string $html The HTML to be injected.
- */
- public function regClientHTMLBlock($html) {
- return $this->regClientScript($html, true);
- }
- /**
- * Returns all registered JavaScripts.
- *
- * @access public
- * @return string The parsed HTML of the client scripts.
- */
- public function getRegisteredClientScripts() {
- $string= '';
- if (is_array($this->jscripts)) {
- $string= implode("\n",$this->jscripts);
- }
- return $string;
- }
- /**
- * Returns all registered startup CSS, JavaScript, or HTML blocks.
- *
- * @access public
- * @return string The parsed HTML of the startup scripts.
- */
- public function getRegisteredClientStartupScripts() {
- $string= '';
- if (is_array ($this->sjscripts)) {
- $string= implode("\n", $this->sjscripts);
- }
- return $string;
- }
- /**
- * Invokes a specified Event with an optional array of parameters.
- *
- * @todo refactor this completely, yuck!!
- *
- * @access public
- * @param string $eventName Name of an event to invoke.
- * @param array $params Optional params provided to the elements registered with an event.
- * @return bool|array
- */
- public function invokeEvent($eventName, array $params= array ()) {
- if (!$eventName)
- return false;
- if ($this->eventMap === null && $this->context instanceof modContext)
- $this->_initEventMap($this->context->get('key'));
- if (!isset ($this->eventMap[$eventName])) {
- //$this->log(modX::LOG_LEVEL_DEBUG,'System event '.$eventName.' was executed but does not exist.');
- return false;
- }
- $results= array ();
- if (count($this->eventMap[$eventName])) {
- $this->event= new modSystemEvent();
- foreach ($this->eventMap[$eventName] as $pluginId => $pluginPropset) {
- $plugin= null;
- if (!version_compare(PHP_VERSION, '5.4', '>=')) {
- $this->Event = & $this->event;
- } else {
- $this->Event = clone $this->event;
- }
- $this->event->resetEventObject();
- $this->event->name= $eventName;
- if (isset ($this->pluginCache[$pluginId])) {
- $plugin= $this->newObject('modPlugin');
- $plugin->fromArray($this->pluginCache[$pluginId], '', true, true);
- $plugin->_processed = false;
- if ($plugin->get('disabled')) {
- $plugin= null;
- }
- } else {
- $plugin= $this->getObject('modPlugin', array ('id' => intval($pluginId), 'disabled' => '0'), true);
- }
- if ($plugin && !$plugin->get('disabled')) {
- $this->event->plugin =& $plugin;
- $this->event->activated= true;
- $this->event->activePlugin= $plugin->get('name');
- $this->event->propertySet= (($pspos = strpos($pluginPropset, ':')) >= 1) ? substr($pluginPropset, $pspos + 1) : '';
- /* merge in plugin properties */
- $eventParams = array_merge($plugin->getProperties(),$params);
- $msg= $plugin->process($eventParams);
- $results[]= $this->event->_output;
- if ($msg && is_string($msg)) {
- $this->log(modX::LOG_LEVEL_ERROR, '[' . $this->event->name . ']' . $msg);
- } elseif ($msg === false) {
- $this->log(modX::LOG_LEVEL_ERROR, '[' . $this->event->name . '] Plugin ' . $plugin->name . ' failed!');
- }
- $this->event->plugin = null;
- $this->event->activePlugin= '';
- $this->event->propertySet= '';
- if (!$this->event->isPropagatable()) {
- break;
- }
- }
- }
- }
- return $results;
- }
- /**
- * Loads and runs a specific processor.
- *
- * @param string $action The processor to run, eg: context/update
- * @param array $scriptProperties Optional. An array of parameters to pass to the processor.
- * @param array $options Optional. An array of options for running the processor, such as:
- *
- * - processors_path - If specified, will override the default MODX processors path.
- * - location - A prefix to load processor files from, will prepend to the action parameter
- * (Note: location will be deprecated in future Revolution versions.)
- *
- * @return mixed The result of the processor.
- */
- public function runProcessor($action = '',$scriptProperties = array(),$options = array()) {
- if (!$this->loadClass('modProcessor','',false,true)) {
- $this->log(modX::LOG_LEVEL_ERROR,'Could not load modProcessor class.');
- return false;
- }
- $result = null;
- /* backwards compat for $options['action']
- * @deprecated Removing in 2.2
- */
- if (empty($action)) {
- if (!empty($options['action'])) {
- $action = $options['action'];
- } else {
- return $result;
- }
- }
- /* calculate processor file path from options and action */
- $isClass = true;
- $processorsPath = isset($options['processors_path']) && !empty($options['processors_path']) ? $options['processors_path'] : $this->config['processors_path'];
- if (isset($options['location']) && !empty($options['location'])) $processorsPath .= ltrim($options['location'],'/') . '/';
- // Prevent path traversal through the action
- $action = preg_replace('/[\.]{2,}/', '', htmlspecialchars($action));
- // Find the processor file, preferring class based processors over old-style processors
- $processorFile = $processorsPath.ltrim($action . '.class.php','/');
- if (!file_exists($processorFile)) {
- $processorFile = $processorsPath.ltrim($action . '.php','/');
- $isClass = false;
- }
- // Prepare a response
- $response = '';
- if (file_exists($processorFile)) {
- if (!isset($this->lexicon)) $this->getService('lexicon', 'modLexicon');
- if (!isset($this->error)) $this->getService('error', 'error.modError');
- if ($isClass) {
- /* ensure processor file is only included once if run multiple times in a request */
- if (!array_key_exists($processorFile,$this->processors)) {
- $className = include_once $processorFile;
- /* handle already included core classes */
- if ($className == 1) {
- $s = explode('/',$action);
- $o = array();
- foreach ($s as $k) {
- $o[] = ucfirst(str_replace(array('.','_','-'),'',$k));
- }
- $className = 'mod'.implode('',$o).'Processor';
- }
- $this->processors[$processorFile] = $className;
- } else {
- $className = $this->processors[$processorFile];
- }
- if (!empty($className)) {
- $processor = call_user_func_array(array($className,'getInstance'),array(&$this,$className,$scriptProperties));
- }
- }
- if (empty($processor)) {
- $processor = new modDeprecatedProcessor($this, $scriptProperties);
- }
- $processor->setPath($processorFile);
- $response = $processor->run();
- } else {
- $this->log(modX::LOG_LEVEL_ERROR, "Processor {$processorFile} does not exist; " . print_r($options, true));
- }
- return $response;
- }
- /**
- * Returns the current user ID, for the current or specified context.
- *
- * @param string $context The key of a valid modContext so you can retrieve
- * the current user ID from a different context than the current.
- * @return integer The ID of the current user.
- */
- public function getLoginUserID($context= '') {
- $userId = 0;
- if (empty($context) && $this->context instanceof modContext && $this->user instanceof modUser) {
- if ($this->user->hasSessionContext($this->context->get('key'))) {
- $userId = $this->user->get('id');
- }
- } else {
- $user = $this->getAuthenticatedUser($context);
- if ($user instanceof modUser) {
- $userId = $user->get('id');
- }
- }
- return $userId;
- }
- /**
- * Returns the current user name, for the current or specified context.
- *
- * @param string $context The key of a valid modContext so you can retrieve
- * the username from a different context than the current.
- * @return string The username of the current user.
- */
- public function getLoginUserName($context= '') {
- $userName = '';
- if (empty($context) && $this->context instanceof modContext && $this->user instanceof modUser) {
- if ($this->user->hasSessionContext($this->context->get('key'))) {
- $userName = $this->user->get('username');
- }
- } else {
- $user = $this->getAuthenticatedUser($context);
- if ($user instanceof modUser) {
- $userName = $user->get('username');
- }
- }
- return $userName;
- }
- /**
- * Returns whether modX instance has been initialized or not.
- *
- * @access public
- * @return boolean
- */
- public function isInitialized() {
- return $this->_initialized;
- }
- /**
- * Legacy fatal error message.
- *
- * @deprecated
- * @param string $msg
- * @param string $query
- * @param bool $is_error
- * @param string $nr
- * @param string $file
- * @param string $source
- * @param string $text
- * @param string $line
- */
- public function messageQuit($msg='unspecified error', $query='', $is_error=true, $nr='', $file='', $source='', $text='', $line='') {
- $this->deprecated('2.2.0', 'Use modX::log with modX::LOG_LEVEL_FATAL instead.');
- $this->log(modX::LOG_LEVEL_FATAL, 'msg: ' . $msg . "\n" . 'query: ' . $query . "\n" . 'nr: ' . $nr . "\n" . 'file: ' . $file . "\n" . 'source: ' . $source . "\n" . 'text: ' . $text . "\n" . 'line: ' . $line . "\n");
- }
- /**
- * Process and return the output from a PHP snippet by name.
- *
- * @param string $snippetName The name of the snippet.
- * @param array $params An associative array of properties to pass to the
- * snippet.
- * @return string The processed output of the snippet.
- */
- public function runSnippet($snippetName, array $params= array ()) {
- $output= '';
- if ($this->getParser()) {
- $snippet= $this->parser->getElement('modSnippet', $snippetName);
- if ($snippet instanceof modSnippet) {
- $snippet->setCacheable(false);
- $output= $snippet->process($params);
- }
- }
- return $output;
- }
- /**
- * Process and return the output from a Chunk by name.
- *
- * @param string $chunkName The name of the chunk.
- * @param array $properties An associative array of properties to process
- * the Chunk with, treated as placeholders within the scope of the Element.
- * @return string The processed output of the Chunk.
- */
- public function getChunk($chunkName, array $properties= array ()) {
- $output= '';
- if ($this->getParser()) {
- $chunk= $this->parser->getElement('modChunk', $chunkName);
- if ($chunk instanceof modChunk) {
- $chunk->setCacheable(false);
- $output= $chunk->process($properties);
- }
- }
- return $output;
- }
- /**
- * Parse a chunk using an associative array of replacement variables.
- *
- * @param string $chunkName The name of the chunk.
- * @param array $chunkArr An array of properties to replace in the chunk.
- * @param string $prefix The placeholder prefix, defaults to [[+.
- * @param string $suffix The placeholder suffix, defaults to ]].
- * @return string The processed chunk with the placeholders replaced.
- */
- public function parseChunk($chunkName, $chunkArr, $prefix='[[+', $suffix=']]') {
- $chunk= $this->getChunk($chunkName);
- if (!empty($chunk) || $chunk === '0') {
- if(is_array($chunkArr)) {
- foreach ($chunkArr as $key => $value) {
- $chunk= str_replace($prefix.$key.$suffix, $value, $chunk);
- }
- }
- }
- return $chunk;
- }
- /**
- * Strip unwanted HTML and PHP tags and supplied patterns from content.
- *
- * @see modX::$sanitizePatterns
- * @param string $html The string to strip
- * @param string $allowed An array of allowed HTML tags
- * @param array $patterns An array of patterns to sanitize with; otherwise will use modX::$sanitizePatterns
- * @param int $depth The depth in which the parser will strip given the patterns specified
- * @return boolean True if anything was stripped
- */
- public function stripTags($html, $allowed= '', $patterns= array(), $depth= 10) {
- $stripped= strip_tags($html, $allowed);
- if (is_array($patterns)) {
- if (empty($patterns)) {
- $patterns = $this->sanitizePatterns;
- }
- foreach ($patterns as $pattern) {
- $depth = ((integer) $depth ? (integer) $depth : 10);
- $iteration = 1;
- while ($iteration <= $depth && preg_match($pattern, $stripped)) {
- $stripped= preg_replace($pattern, '', $stripped);
- $iteration++;
- }
- }
- }
- return $stripped;
- }
- /**
- * Returns true if user has the specified policy permission.
- *
- * @param string $pm Permission key to check.
- * @return boolean
- */
- public function hasPermission($pm) {
- $state = $this->context->checkPolicy($pm);
- return $state;
- }
- /**
- * Logs a manager action.
- *
- * @param string $action The action to pull from the lexicon module.
- * @param string $class_key The class key that the action is being performed on.
- * @param mixed $item The primary key id or array of keys to grab the object with.
- * @param int|null $userId
- * @return modManagerLog The newly created modManagerLog object.
- */
- public function logManagerAction($action, $class_key, $item, $userId = null) {
- if($userId === null) {
- if ($this->user instanceof modUser) {
- $userId = $this->user->get('id');
- }
- }
- $ml = $this->newObject('modManagerLog');
- $ml->set('user', (integer) $userId);
- $ml->set('occurred', strftime('%Y-%m-%d %H:%M:%S'));
- $ml->set('action', empty($action) ? 'unknown' : $action);
- $ml->set('classKey', empty($class_key) ? '' : $class_key);
- $ml->set('item', empty($item) ? 'unknown' : $item);
- if (!$ml->save()) {
- $this->log(modX::LOG_LEVEL_ERROR, $this->lexicon('manager_log_err_save'));
- return null;
- }
- return $ml;
- }
- /**
- * Remove an event from the eventMap so it will not be invoked.
- *
- * @param string $event
- * @param integer $pluginId Plugin identifier to remove from the eventMap for the specified event.
- * @return boolean false if the event parameter is not specified or is not
- * present in the eventMap.
- */
- public function removeEventListener($event, $pluginId = 0) {
- $removed = false;
- if (!empty($event) && isset($this->eventMap[$event])) {
- if (intval($pluginId)) {
- unset ($this->eventMap[$event][$pluginId]);
- } else {
- unset ($this->eventMap[$event]);
- }
- $removed = true;
- }
- return $removed;
- }
- /**
- * Remove all registered events for the current request.
- */
- public function removeAllEventListener() {
- unset ($this->eventMap);
- $this->eventMap= array ();
- }
- /**
- * Add a plugin to the eventMap within the current execution cycle.
- *
- * @param string $event Name of the event.
- * @param integer $pluginId Plugin identifier to add to the event.
- * @param string $propertySetName The name of property set bound to the plugin
- * @return boolean true if the event is successfully added, otherwise false.
- */
- public function addEventListener($event, $pluginId, $propertySetName = '') {
- $added = false;
- $pluginId = intval($pluginId);
- if ($event && $pluginId) {
- if (!isset($this->eventMap[$event]) || empty ($this->eventMap[$event])) {
- $this->eventMap[$event]= array();
- }
- $this->eventMap[$event][$pluginId]= $pluginId . (!empty($propertySetName) ? ':' . $propertySetName : '');
- $added = true;
- }
- return $added;
- }
- /**
- * Switches the primary Context for the modX instance.
- *
- * Be aware that switching contexts does not allow custom session handling
- * classes to be loaded. The gateway defines the session handling that is
- * applied to a single request. To create a context with a custom session
- * handler you must create a unique context gateway that initializes that
- * context directly.
- *
- * @param string $contextKey The key of the context to switch to.
- * @param boolean $reload Set to true to force the context data to be regenerated
- * before being switched to.
- * @return boolean True if the switch was successful, otherwise false.
- */
- public function switchContext($contextKey, $reload = false) {
- $switched= false;
- if ($this->context->key != $contextKey) {
- $switched= $this->_initContext($contextKey, $reload);
- if ($switched) {
- if (is_array($this->config)) {
- $this->setPlaceholders($this->config, '+');
- }
- }
- }
- return $switched;
- }
- /**
- * Retrieve a context by name without initializing it.
- *
- * Within a request, contexts retrieved using this function will cache the
- * context data into the modX::$contexts array to avoid loading the same
- * context multiple times.
- *
- * @access public
- * @param string $contextKey The context to retrieve.
- * @return modContext A modContext object retrieved from cache or
- * database.
- */
- public function getContext($contextKey) {
- if (!isset($this->contexts[$contextKey])) {
- $this->contexts[$contextKey]= $this->getObject('modContext', array('key' => $contextKey));
- if ($this->contexts[$contextKey]) {
- $this->contexts[$contextKey]->prepare();
- }
- }
- return $this->contexts[$contextKey];
- }
- /**
- * Gets a map of events and registered plugins for the specified context.
- *
- * Service #s:
- * 1 - Parser Service Events
- * 2 - Manager Access Events
- * 3 - Web Access Service Events
- * 4 - Cache Service Events
- * 5 - Template Service Events
- * 6 - User Defined Events
- *
- * @param string $contextKey Context identifier.
- * @return array A map of events and registered plugins for each.
- */
- public function getEventMap($contextKey) {
- $eventElementMap= array ();
- if ($contextKey) {
- switch ($contextKey) {
- case 'mgr':
- /* dont load Web Access Service Events */
- $service= "Event.service IN (1,2,4,5,6) AND";
- break;
- default:
- /* dont load Manager Access Events */
- $service= "Event.service IN (1,3,4,5,6) AND";
- }
- $pluginEventTbl= $this->getTableName('modPluginEvent');
- $eventTbl= $this->getTableName('modEvent');
- $pluginTbl= $this->getTableName('modPlugin');
- $propsetTbl= $this->getTableName('modPropertySet');
- $sql= "
- SELECT
- Event.name AS event,
- PluginEvent.pluginid,
- PropertySet.name AS propertyset
- FROM {$pluginEventTbl} PluginEvent
- INNER JOIN {$pluginTbl} Plugin ON Plugin.id = PluginEvent.pluginid AND Plugin.disabled = 0
- INNER JOIN {$eventTbl} Event ON {$service} Event.name = PluginEvent.event
- LEFT JOIN {$propsetTbl} PropertySet ON PluginEvent.propertyset = PropertySet.id
- ORDER BY Event.name, PluginEvent.priority ASC
- ";
- $stmt= $this->prepare($sql);
- if ($stmt && $stmt->execute()) {
- while ($ee = $stmt->fetch(PDO::FETCH_ASSOC)) {
- $eventElementMap[$ee['event']][(string) $ee['pluginid']]= $ee['pluginid'] . (!empty($ee['propertyset']) ? ':' . $ee['propertyset'] : '');
- }
- }
- }
- return $eventElementMap;
- }
- /**
- * Checks for locking on a page.
- *
- * @param integer $id Id of the user checking for a lock.
- * @param string $action The action identifying what is locked.
- * @param string $type Message indicating the kind of lock being checked.
- * @return string|boolean If locked, will return a locked message
- */
- public function checkForLocks($id,$action,$type) {
- $msg= false;
- $id= intval($id);
- if (!$id) $id= $this->getLoginUserID();
- if ($au = $this->getObject('modActiveUser',array('action' => $action, 'internalKey:!=' => $id))) {
- $msg = $this->lexicon('lock_msg',array(
- 'name' => $au->get('username'),
- 'object' => $type,
- ));
- }
- return $msg;
- }
- /**
- * Grabs a processed lexicon string.
- *
- * @access public
- * @param string $key
- * @param array $params
- * @param string $language
- * @return null|string The translated string, or null if none is set
- */
- public function lexicon($key,$params = array(),$language = '') {
- $language = !empty($language) ? $language : $this->getOption('cultureKey',null,'en');
- if ($this->lexicon) {
- return $this->lexicon->process($key,$params,$language);
- } else {
- $this->log(modX::LOG_LEVEL_ERROR,'Culture not initialized; cannot use lexicon.');
- }
- return null;
- }
- /**
- * Returns the state of the SESSION being used by modX.
- *
- * The possible values for session state are:
- *
- * modX::SESSION_STATE_UNINITIALIZED
- * modX::SESSION_STATE_UNAVAILABLE
- * modX::SESSION_STATE_EXTERNAL
- * modX::SESSION_STATE_INITIALIZED
- *
- * @return integer Returns an integer representing the session state.
- */
- public function getSessionState() {
- if ($this->_sessionState !== modX::SESSION_STATE_INITIALIZED) {
- if (XPDO_CLI_MODE || headers_sent()) {
- $this->_sessionState = modX::SESSION_STATE_UNAVAILABLE;
- }
- elseif (isset($_SESSION)) {
- $this->_sessionState = modX::SESSION_STATE_EXTERNAL;
- }
- }
- return $this->_sessionState;
- }
- /**
- * Executed before parser processing of an element.
- */
- public function beforeProcessing() {}
- /**
- * Executed before the response is rendered.
- */
- public function beforeRender() {}
- /**
- * Executed before the handleRequest function.
- */
- public function beforeRequest() {
- unset($this->placeholders['+username'],$this->placeholders['+password'],$this->placeholders['+dbname'],$this->placeholders['+host']);
- }
- /**
- * Determines the current site_status.
- *
- * @return boolean True if the site is online or the user has a valid
- * user session in the 'mgr' context; false otherwise.
- */
- public function checkSiteStatus() {
- $status = false;
- if ($this->config['site_status'] == '1' || ($this->getSessionState() === modX::SESSION_STATE_INITIALIZED && $this->hasPermission('view_offline'))) {
- $status = true;
- }
- return $status;
- }
- /**
- * Add an extension package to MODX
- *
- * @param string $name
- * @param string $path
- * @param array $options
- * @return boolean
- */
- public function addExtensionPackage($name,$path,array $options = array()) {
- $extPackages = $this->getOption('extension_packages');
- $extPackages = !empty($extPackages) ? $extPackages : array();
- $extPackages = is_array($extPackages) ? $extPackages : $this->fromJSON($extPackages);
- $extPackages[$name] = $options;
- $extPackages['path'] = $path;
- /** @var modSystemSetting $setting */
- $setting = $this->getObject('modSystemSetting',array(
- 'key' => 'extension_packages',
- ));
- if (empty($setting)) {
- $setting = $this->newObject('modSystemSetting');
- $setting->set('key','extension_packages');
- $setting->set('namespace','core');
- $setting->set('xtype','textfield');
- $setting->set('area','system');
- }
- $value = $setting->get('value');
- $value = is_array($value) ? $value : $this->fromJSON($value);
- if (empty($value)) {
- $value = array();
- $value[$name] = $options;
- $value[$name]['path'] = $path;
- $value = '['.$this->toJSON($value).']';
- } else {
- $found = false;
- foreach ($value as $k => $v) {
- foreach ($v as $kk => $vv) {
- if ($kk == $name) {
- $found = true;
- }
- }
- }
- if (!$found) {
- $extPack[$name] = $options;
- $extPack[$name]['path'] = $path;
- $value[] = $extPack;
- }
- $value = $this->toJSON($value);
- }
- $value = str_replace('\\','',$value);
- $setting->set('value',$value);
- return $setting->save();
- }
- /**
- * Remove an extension package from MODX
- *
- * @param string $name
- * @return boolean
- */
- public function removeExtensionPackage($name) {
- /** @var modSystemSetting $setting */
- $setting = $this->getObject('modSystemSetting',array(
- 'key' => 'extension_packages',
- ));
- if (!$setting) {
- return false;
- }
- $value = $setting->get('value');
- $value = is_array($value) ? $value : $this->fromJSON($value);
- $found = false;
- foreach ($value as $idx => $extPack) {
- foreach ($extPack as $key => $opt) {
- if ($key == $name) {
- unset($value[$idx]);
- $found = true;
- }
- }
- }
- $removed = false;
- if ($found) {
- $value = $this->toJSON($value);
- $value = str_replace('\\','',$value);
- $setting->set('value',$value);
- $removed = $setting->save();
- }
- return $removed;
- }
- /**
- * Reload data for a specified Context, without switching to it.
- *
- * Note that the Context will be loaded even if it is not already.
- *
- * @param string $key The key of the Context to (re)load.
- * @return boolean True if the Context was (re)loaded successfully; false otherwise.
- */
- public function reloadContext($key = null) {
- $reloaded = false;
- if ($this->context instanceof modContext) {
- if (empty($key)) {
- $key = $this->context->get('key');
- }
- if ($key === $this->context->get('key')) {
- $reloaded = $this->_initContext($key, true);
- if ($reloaded && is_array($this->config)) {
- $this->setPlaceholders($this->config, '+');
- }
- } else {
- if (!array_key_exists($key, $this->contexts) || !($this->contexts[$key] instanceof modContext)) {
- $this->contexts[$key] = $this->newObject('modContext');
- $this->contexts[$key]->_fields['key']= $key;
- }
- $reloaded = $this->contexts[$key]->prepare(true);
- }
- } elseif (!empty($key) && (!array_key_exists($key, $this->contexts) || !($this->contexts[$key] instanceof modContext))) {
- $this->contexts[$key] = $this->newObject('modContext');
- $this->contexts[$key]->_fields['key']= $key;
- $reloaded = $this->contexts[$key]->prepare(true);
- }
- return $reloaded;
- }
- /**
- * Start a PHP Session if one is not already available.
- *
- * @return bool Returns true if a session is successfully or already started, false otherwise.
- */
- public function startSession()
- {
- if ($this->_sessionState === modX::SESSION_STATE_UNINITIALIZED) {
- if (!session_start()) {
- $this->_sessionState = isset($_SESSION)
- ? modX::SESSION_STATE_EXTERNAL
- : modX::SESSION_STATE_UNAVAILABLE;
- } elseif (isset($_SESSION)) {
- $this->_sessionState = modX::SESSION_STATE_INITIALIZED;
- }
- }
- return isset($_SESSION);
- }
- /**
- * Marks the calling function as deprecated, sending a message into the error log.
- *
- * This automatically determines where the deprecated method was called from, and
- * includes that in the log message.
- *
- * @param string $since The version the function was marked as deprecated
- * @param string $recommendation A description or recommendation on what to replace a method with
- * @param string $deprecatedDef Can be used to override the definition (i.e. function name) for the log; useful if not a specific method but an entire entity is deprecated.
- */
- public function deprecated($since, $recommendation = '', $deprecatedDef = '')
- {
- if (!$this->getOption('log_deprecated', null, true)) {
- return;
- }
- // We use the trace to identify both the method that is deprecated, and the caller
- $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
- $deprecatedMethod = isset($trace[1]) ? $trace[1] : array();
- $caller = isset($trace[2]) ? $trace[2] : array();
- // Format the deprecated function definition with the class, if it has one
- if ($deprecatedDef === '') {
- $deprecatedDef = isset($deprecatedMethod['class'])
- ? $deprecatedMethod['class'] . '::' . $deprecatedMethod['function']
- : $deprecatedMethod['function'];
- }
- $callerDef = isset($caller['class']) ? $caller['class'] . '::' . $caller['function'] : '';
- // The message that gets logged
- $msg = $deprecatedDef . ' is deprecated since version ' . $since . '. ' . $recommendation;
- // Only log deprecated functions once - even when called many times in a single request.
- if (in_array($msg.$callerDef, $this->loggedDeprecatedFunctions, true)) {
- return;
- }
- $this->loggedDeprecatedFunctions[] = $msg.$callerDef;
- // Send to the standard log, providing also the file and line the deprecated method was called from
- $this->log(self::LOG_LEVEL_ERROR, $msg, '', $callerDef, $deprecatedMethod['file'], $deprecatedMethod['line']);
- }
- /**
- * Loads a specified Context.
- *
- * Merges any context settings with the modX::$config, and performs any
- * other context specific initialization tasks.
- *
- * @access protected
- * @param string $contextKey A context identifier.
- * @param boolean $regenerate If true, force regeneration of the context even if already initialized.
- * @param array $options Array of options to override context settings.
- * @return boolean True if the context was properly initialized.
- */
- protected function _initContext($contextKey, $regenerate = false, $options = null) {
- $initialized= false;
- $oldContext = is_object($this->context) ? $this->context->get('key') : '';
- if (isset($this->contexts[$contextKey]) && $this->contexts[$contextKey] instanceof modContext) {
- $this->context= & $this->contexts[$contextKey];
- } else {
- $this->context= $this->newObject('modContext');
- $this->context->_fields['key']= $contextKey;
- if (!$this->context->validate()) {
- $this->log(modX::LOG_LEVEL_ERROR, 'No valid context specified: ' . $contextKey);
- $this->context = null;
- }
- }
- if ($this->context) {
- if (!$this->context->prepare((boolean) $regenerate, is_array($options) ? $options : array())) {
- $this->context= null;
- $this->log(modX::LOG_LEVEL_ERROR, 'Could not prepare context: ' . $contextKey);
- } else {
- //This fixes error with multiple contexts
- $this->contexts[$contextKey]=$this->context;
- if ($this->context->checkPolicy('load')) {
- $this->aliasMap= & $this->context->aliasMap;
- $this->resourceMap= & $this->context->resourceMap;
- $this->eventMap= & $this->context->eventMap;
- $this->pluginCache= & $this->context->pluginCache;
- $this->config= array_merge($this->_systemConfig, $this->context->config);
- $iniTZ = ini_get('date.timezone');
- $cfgTZ = $this->getOption('date_timezone', $options, '');
- if (!empty($cfgTZ)) {
- if (empty($iniTZ) || $iniTZ !== $cfgTZ) {
- date_default_timezone_set($cfgTZ);
- }
- } elseif (empty($iniTZ)) {
- date_default_timezone_set('UTC');
- }
- if ($this->_initialized) {
- $this->user = null;
- $this->getUser();
- }
- $initialized = true;
- } elseif (isset($this->contexts[$oldContext])) {
- $this->context =& $this->contexts[$oldContext];
- } else {
- $this->log(modX::LOG_LEVEL_ERROR, 'Could not load context: ' . $contextKey);
- }
- }
- }
- if ($initialized) {
- $this->setLogLevel($this->getOption('log_level', $options, xPDO::LOG_LEVEL_ERROR));
-
- $logTarget = $this->getOption('log_target', $options, 'FILE', true);
- if ($logTarget === 'FILE') {
- $options = array();
- $filename = $this->getOption('error_log_filename', $options, '');
- if (!empty($filename)) $options['filename'] = $filename;
- $filepath = $this->getOption('error_log_filepath', $options, '');
- if (!empty($filepath)) $options['filepath'] = rtrim($filepath, '/') . '/';
- $this->setLogTarget(array(
- 'target' => 'FILE',
- 'options' => $options
- ));
- } else {
- $this->setLogTarget($logTarget);
- }
-
- $debug = $this->getOption('debug');
- if (!is_null($debug) && $debug !== '') {
- $this->setDebug($debug);
- }
- }
- return $initialized;
- }
- /**
- * Initializes the culture settings.
- *
- * @param array|null $options Options for the culture initialization process.
- */
- protected function _initCulture($options = null) {
- $cultureKey = $this->getOption('cultureKey', $options, 'en');
- if (!empty($_SESSION['cultureKey'])) $cultureKey = $_SESSION['cultureKey'];
- if (!empty($_REQUEST['cultureKey'])) $cultureKey = $_REQUEST['cultureKey'];
- $this->cultureKey = $cultureKey;
- $this->setOption('cultureKey', $cultureKey);
- if ($this->getOption('setlocale', $options, true)) {
- $locale = setlocale(LC_ALL, null);
- $result = setlocale(LC_ALL, $this->getOption('locale', null, $locale));
- if ($result === false) {
- $this->log(modX::LOG_LEVEL_ERROR, 'Could not set the locale. Please check if the locale ' . $this->getOption('locale', null, $locale) . ' exists on your system');
- }
- }
- $this->getService('lexicon', $this->getOption('lexicon_class', $options, 'modLexicon'), '', is_array($options) ? $options : array());
- $this->invokeEvent('OnInitCulture');
- }
- /**
- * Loads the error handler for this instance.
- *
- * @param array|null $options An array of options for the errorHandler.
- */
- protected function _initErrorHandler($options = null) {
- if ($this->errorHandler == null || !is_object($this->errorHandler)) {
- if ($ehClass = $this->getOption('error_handler_class', $options, 'modErrorHandler', true)) {
- $ehPath = $this->getOption('error_handler_path', $options, '', true);
- if ($ehClass = $this->loadClass($ehClass, $ehPath, false, true)) {
- if ($this->errorHandler = new $ehClass($this)) {
- $result = set_error_handler(array ($this->errorHandler, 'handleError'), $this->getOption('error_handler_types', $options, error_reporting(), true));
- if ($result === false) {
- $this->log(modX::LOG_LEVEL_ERROR, 'Could not set error handler. Make sure your class has a function called handleError(). Result: ' . print_r($result, true));
- }
- }
- }
- }
- }
- }
- /**
- * Populates the map of events and registered plugins for each.
- *
- * @param string $contextKey Context identifier.
- */
- protected function _initEventMap($contextKey) {
- if ($this->eventMap === null) {
- $this->eventMap= $this->getEventMap($contextKey);
- }
- }
- /**
- * Loads the session handler and starts the session.
- *
- * @param array|null $options Options to override Settings explicitly.
- */
- protected function _initSession($options = null) {
- $contextKey= $this->context instanceof modContext ? $this->context->get('key') : null;
- if ($this->getOption('session_enabled', $options, true) || isset($_GET['preview'])) {
- if (!in_array($this->getSessionState(), array(modX::SESSION_STATE_INITIALIZED, modX::SESSION_STATE_EXTERNAL, modX::SESSION_STATE_UNAVAILABLE), true)) {
- $sh = false;
- if ($sessionHandlerClass = $this->getOption('session_handler_class', $options)) {
- if ($shClass = $this->loadClass($sessionHandlerClass, '', false, true)) {
- if ($sh = new $shClass($this)) {
- session_set_save_handler(
- array (& $sh, 'open'),
- array (& $sh, 'close'),
- array (& $sh, 'read'),
- array (& $sh, 'write'),
- array (& $sh, 'destroy'),
- array (& $sh, 'gc')
- );
- }
- }
- }
- if (
- (is_string($sessionHandlerClass) && !$sh instanceof $sessionHandlerClass) ||
- !is_string($sessionHandlerClass)
- ) {
- $sessionSavePath = $this->getOption('session_save_path', $options);
- if ($sessionSavePath && is_writable($sessionSavePath)) {
- session_save_path($sessionSavePath);
- }
- }
- $cookieDomain= $this->getOption('session_cookie_domain', $options, '');
- $cookiePath= $this->getOption('session_cookie_path', $options, MODX_BASE_URL);
- if (empty($cookiePath)) $cookiePath = $this->getOption('base_url', $options, MODX_BASE_URL);
- $cookieSecure= (boolean) $this->getOption('session_cookie_secure', $options, false);
- $cookieHttpOnly= (boolean) $this->getOption('session_cookie_httponly', $options, true);
- $cookieLifetime= (integer) $this->getOption('session_cookie_lifetime', $options, 0);
- $gcMaxlifetime = (integer) $this->getOption('session_gc_maxlifetime', $options, $cookieLifetime);
- if ($gcMaxlifetime > 0) {
- ini_set('session.gc_maxlifetime', $gcMaxlifetime);
- }
- $site_sessionname = $this->getOption('session_name', $options, '');
- if (!empty($site_sessionname)) session_name($site_sessionname);
- session_set_cookie_params($cookieLifetime, $cookiePath, $cookieDomain, $cookieSecure, $cookieHttpOnly);
- if ($this->getOption('anonymous_sessions', $options, true) || isset($_COOKIE[session_name()])) {
- if (!$this->startSession()) {
- $this->log(modX::LOG_LEVEL_ERROR, 'Unable to initialize a session', '', __METHOD__, __FILE__, __LINE__);
- $this->getUser($contextKey);
- return;
- }
- $this->getUser($contextKey);
- $cookieExpiration = 0;
- if (isset ($_SESSION['modx.' . $contextKey . '.session.cookie.lifetime'])) {
- $sessionCookieLifetime = (integer)$_SESSION['modx.' . $contextKey . '.session.cookie.lifetime'];
- if ($sessionCookieLifetime !== $cookieLifetime) {
- if ($sessionCookieLifetime) {
- $cookieExpiration = time() + $sessionCookieLifetime;
- }
- setcookie(session_name(), session_id(), $cookieExpiration, $cookiePath, $cookieDomain,
- $cookieSecure, $cookieHttpOnly);
- }
- }
- } else {
- $this->getUser($contextKey);
- }
- } else {
- $this->getUser($contextKey);
- }
- } else {
- $this->getUser($contextKey);
- }
- }
- /**
- * Loads the modX system configuration settings.
- *
- * @access protected
- * @return boolean True if successful.
- */
- protected function _loadConfig() {
- $this->config = $this->_config;
- $this->getCacheManager();
- $config = $this->cacheManager->get('config', array(
- xPDO::OPT_CACHE_KEY => $this->getOption('cache_system_settings_key', null, 'system_settings'),
- xPDO::OPT_CACHE_HANDLER => $this->getOption('cache_system_settings_handler', null, $this->getOption(xPDO::OPT_CACHE_HANDLER)),
- xPDO::OPT_CACHE_FORMAT => (integer) $this->getOption('cache_system_settings_format', null, $this->getOption(xPDO::OPT_CACHE_FORMAT, null, xPDOCacheManager::CACHE_PHP))
- ));
- if (empty($config)) {
- $config = $this->cacheManager->generateConfig();
- }
- if (empty($config)) {
- $config = array();
- if (!$settings = $this->getCollection('modSystemSetting')) {
- return false;
- }
- foreach ($settings as $setting) {
- $config[$setting->get('key')]= $setting->get('value');
- }
- }
- $this->config = array_merge($this->config, $config);
- $this->_systemConfig = $this->config;
- return true;
- }
- /**
- * Provides modX the ability to use modRegister instances as log targets.
- *
- * {@inheritdoc}
- */
- protected function _log($level, $msg, $target= '', $def= '', $file= '', $line= '') {
- if (empty($target)) {
- $target = $this->logTarget;
- }
- $targetOptions = array();
- $targetObj = $target;
- if (is_array($target)) {
- if (isset($target['options'])) $targetOptions = $target['options'];
- $targetObj = isset($target['target']) ? $target['target'] : 'ECHO';
- }
- if (is_object($targetObj) && $targetObj instanceof modRegister) {
- if ($level === modX::LOG_LEVEL_FATAL) {
- if (empty ($file)) $file= (isset ($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : (isset ($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : '');
- $this->_logInRegister($targetObj, $level, $msg, $def, $file, $line);
- $this->sendError('fatal');
- }
- if ($this->_debug === true || $level <= $this->logLevel) {
- if (empty ($file)) $file= (isset ($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : (isset ($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : '');
- $this->_logInRegister($targetObj, $level, $msg, $def, $file, $line);
- }
- } else {
- if ($level === modX::LOG_LEVEL_FATAL) {
- while (ob_get_level() && @ob_end_clean()) {}
- if ($targetObj == 'FILE' && $cacheManager= $this->getCacheManager()) {
- $filename = isset($targetOptions['filename']) ? $targetOptions['filename'] : 'error.log';
- $filepath = isset($targetOptions['filepath']) ? $targetOptions['filepath'] : $this->getCachePath() . xPDOCacheManager::LOG_DIR;
- $cacheManager->writeFile($filepath . $filename, '[' . strftime('%Y-%m-%d %H:%M:%S') . '] (' . $this->_getLogLevel($level) . $def . $file . $line . ') ' . $msg . "\n" . ($this->getDebug() === true ? '<pre>' . "\n" . print_r(debug_backtrace(), true) . "\n" . '</pre>' : ''), 'a');
- }
- $this->sendError('fatal');
- }
- parent :: _log($level, $msg, $target, $def, $file, $line);
- }
- }
- /**
- * Provides custom logging functionality for modRegister targets.
- *
- * @access protected
- * @param modRegister $register The modRegister instance to send to
- * @param int $level The level of error or message that occurred
- * @param string $msg The message to send to the register
- * @param string $def The type of error that occurred
- * @param string $file The filename of the file that the message occurs for
- * @param string $line The line number of the file that the message occurs for
- */
- protected function _logInRegister($register, $level, $msg, $def, $file, $line) {
- $timestamp = strftime('%Y-%m-%d %H:%M:%S');
- $messageKey = (string) time();
- $messageKey .= '-' . sprintf("%06d", $this->_logSequence);
- $message = array(
- 'timestamp' => $timestamp,
- 'level' => $this->_getLogLevel($level),
- 'msg' => $msg,
- 'def' => $def,
- 'file' => $file,
- 'line' => $line
- );
- $options = array();
- if ($level === xPDO::LOG_LEVEL_FATAL) {
- $options['kill'] = true;
- }
- $register->send('', array($messageKey => $message), $options);
- $this->_logSequence++;
- }
- /**
- * Executed after the response is sent and execution is completed.
- *
- * @access protected
- */
- public function _postProcess() {
- if ($this->resourceGenerated && $this->getOption('cache_resource', null, true)) {
- if (is_object($this->resource) && $this->resource instanceof modResource && $this->resource->get('id') && $this->resource->get('cacheable')) {
- $this->resource->_contextKey = $this->context->get('key');
- $this->invokeEvent('OnBeforeSaveWebPageCache');
- $this->cacheManager->generateResource($this->resource);
- }
- }
- $this->invokeEvent('OnWebPageComplete');
- }
- }
- /**
- * Represents a modEvent when invoking events.
- * @package modx
- */
- class modSystemEvent {
- /**
- * @var string For new creations of objects in model events
- */
- const MODE_NEW = 'new';
- /**
- * @var string For updating objects in model events
- */
- const MODE_UPD = 'upd';
- /**
- * The name of the Event
- * @var string $name
- */
- public $name = '';
- /**
- * The name of the active plugin being invoked
- * @var string $activePlugin
- * @deprecated
- */
- public $activePlugin = '';
- /**
- * A reference/instance of the currently processed modPlugin object
- *
- * @var modPlugin|null
- */
- public $plugin = null;
- /**
- * @var string The name of the active property set for the invoked Event
- * @deprecated
- */
- public $propertySet = '';
- /**
- * Whether or not to allow further execution of Plugins for this event
- * @var boolean $_propagate
- */
- protected $_propagate = true;
- /**
- * The current output for the event
- * @var string $_output
- */
- public $_output;
- /**
- * Whether or not this event has been activated
- * @var boolean
- */
- public $activated;
- /**
- * Any returned values for this event
- * @var mixed $returnedValues
- */
- public $returnedValues;
- /**
- * Any params passed to this event
- * @var array $params
- */
- public $params;
- /**
- * Display a message to the user during the event.
- *
- * @todo Remove this; the centralized modRegistry will handle configurable
- * logging of any kind of message or data to any repository or output
- * context. Use {@link modX::_log()} in the meantime.
- * @param string $msg The message to display.
- */
- public function alert($msg) {}
- /**
- * Render output from the event.
- * @param string $output The output to render.
- */
- public function output($output) {
- if ($this->_output === '') {
- $this->_output = $output;
- } else {
- $this->_output .= $output;
- }
- }
- /**
- * Stop further execution of plugins for this event.
- */
- public function stopPropagation() {
- $this->_propagate = false;
- }
- /**
- * Returns whether the event will propagate or not.
- *
- * @access public
- * @return boolean
- */
- public function isPropagatable() {
- return $this->_propagate;
- }
- /**
- * Reset the event instance for reuse.
- */
- public function resetEventObject(){
- $this->returnedValues = null;
- $this->name = '';
- $this->_output = '';
- $this->_propagate = true;
- $this->activated = false;
- }
- }
|