diff --git a/README.md b/README.md index 57de10dc..8f8beb3a 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,26 @@ ## pdoTools -Small library for creating fast snippets for MODX Revolution that works through PDO. +Library for MODX Revolution for creating fast snippets and using file elements instead of DB elements. It's used by Tickets and miniShop2. -Required by Tickets and miniShop2. - -## Main features -- Builds queries with xPDO. +### Main features +- Building queries with xPDO. - Retrieve results with PDO. -- Improved pdoTools::getChunk() function, that processing placeholders faster, than original modX::getChunk(). +- Includes Fenom template engine. +- New pdoTools::getChunk() function, that processing placeholders faster than original modX::getChunk(). +- New pdoTools::runSnippet() function, that is faster and more powerful than original modX::runSnippet(). +- Added functionality of file elements. +- Includes some snippets for convenient and fast development. + - pdoResources + - pdoMenu + - pdoCrumbs + - pdoPage + - pdoSitemap + - pdoUsers + - pdoTitle + - pdoField + - pdoArchive + - pdoNeighbor pdoTools snippets will work so faster, than more fields you will retrieve from database at one query. + +\* Required by Tickets and miniShop2. diff --git a/_build/build.config.php b/_build/build.config.php index 9c44073a..f6effe8c 100644 --- a/_build/build.config.php +++ b/_build/build.config.php @@ -1,53 +1,50 @@ $root, 'build' => $root . '_build/', 'data' => $root . '_build/data/', @@ -27,8 +27,9 @@ 'docs' => $root . 'core/components/' . PKG_NAME_LOWER . '/docs/', 'source_assets' => $root . 'assets/components/' . PKG_NAME_LOWER, 'source_core' => $root . 'core/components/' . PKG_NAME_LOWER, + 'validators' => $root . '_build/validators/', 'resolvers' => $root . '_build/resolvers/', -); +]; unset($root); /* override with your own defines here (see build.config.sample.php) */ @@ -40,95 +41,55 @@ echo '
'; /* used for nice formatting of log messages */ $modx->setLogLevel(modX::LOG_LEVEL_INFO); $modx->setLogTarget('ECHO'); -$modx->getService('error', 'error.modError'); +$modx->services->add('error', new modError($modx)); +$modx->error = $modx->services->get('error'); -$modx->loadClass('transport.modPackageBuilder', '', false, true); $builder = new modPackageBuilder($modx); $builder->createPackage(PKG_NAME_LOWER, PKG_VERSION, PKG_RELEASE); $builder->registerNamespace(PKG_NAME_LOWER, false, true, '{core_path}components/' . PKG_NAME_LOWER . '/'); $modx->log(modX::LOG_LEVEL_INFO, 'Created Transport Package and Namespace.'); -/* load system settings */ -if (defined('BUILD_SETTING_UPDATE')) { - $settings = include $sources['data'] . 'transport.settings.php'; - if (!is_array($settings)) { - $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in settings.'); - } else { - $attributes = array( - xPDOTransport::UNIQUE_KEY => 'key', - xPDOTransport::PRESERVE_KEYS => true, - xPDOTransport::UPDATE_OBJECT => BUILD_SETTING_UPDATE, - ); - foreach ($settings as $setting) { - $vehicle = $builder->createVehicle($setting, $attributes); - $builder->putVehicle($vehicle); - } - $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($settings) . ' System Settings.'); - } - unset($settings, $setting, $attributes); -} - -/* load plugins events */ -if (defined('BUILD_EVENT_UPDATE')) { - $events = include $sources['data'] . 'transport.events.php'; - if (!is_array($events)) { - $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in events.'); - } else { - $attributes = array( - xPDOTransport::PRESERVE_KEYS => true, - xPDOTransport::UPDATE_OBJECT => BUILD_EVENT_UPDATE, - ); - foreach ($events as $event) { - $vehicle = $builder->createVehicle($event, $attributes); - $builder->putVehicle($vehicle); - } - $modx->log(xPDO::LOG_LEVEL_INFO, 'Packaged in ' . count($events) . ' Plugins events.'); - } - unset ($events, $event, $attributes); -} - -/* create category */ -$category = $modx->newObject('modCategory'); +// create category +$category = $modx->newObject(modCategory::class); $category->set('id', 1); $category->set('category', PKG_NAME); - -/* add snippets */ -$snippets = include $sources['data'] . 'transport.snippets.php'; -if (!is_array($snippets)) { - $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in snippets.'); -} else { - $category->addMany($snippets); - $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($snippets) . ' snippets.'); -} - - -/* create category vehicle */ -$attr = array( +// create category vehicle +$attr = [ xPDOTransport::UNIQUE_KEY => 'category', xPDOTransport::PRESERVE_KEYS => false, xPDOTransport::UPDATE_OBJECT => true, - xPDOTransport::RELATED_OBJECTS => true, - xPDOTransport::RELATED_OBJECT_ATTRIBUTES => array( - 'Snippets' => array( - xPDOTransport::PRESERVE_KEYS => false, - xPDOTransport::UPDATE_OBJECT => BUILD_SNIPPET_UPDATE, - xPDOTransport::UNIQUE_KEY => 'name', - ), - ), -); - -/* add plugins */ + xPDOTransport::ABORT_INSTALL_ON_VEHICLE_FAIL => true, + xPDOTransport::RELATED_OBJECT_ATTRIBUTES => [], +]; + +// add snippets +if (defined('BUILD_SNIPPET_UPDATE')) { + $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Snippets'] = [ + xPDOTransport::PRESERVE_KEYS => false, + xPDOTransport::UPDATE_OBJECT => BUILD_SNIPPET_UPDATE, + xPDOTransport::UNIQUE_KEY => 'name', + ]; + $snippets = include $sources['data'] . 'transport.snippets.php'; + if (!is_array($snippets)) { + $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in snippets.'); + } else { + $category->addMany($snippets); + $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($snippets) . ' snippets.'); + } +} + +// add plugins if (defined('BUILD_PLUGIN_UPDATE')) { - $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Plugins'] = array( + $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Plugins'] = [ xPDOTransport::PRESERVE_KEYS => false, xPDOTransport::UPDATE_OBJECT => BUILD_PLUGIN_UPDATE, xPDOTransport::UNIQUE_KEY => 'name', - ); - $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['PluginEvents'] = array( + ]; + $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['PluginEvents'] = [ xPDOTransport::PRESERVE_KEYS => true, xPDOTransport::UPDATE_OBJECT => BUILD_PLUGIN_UPDATE, - xPDOTransport::UNIQUE_KEY => array('pluginid', 'event'), - ); + xPDOTransport::UNIQUE_KEY => ['pluginid', 'event'], + ]; $plugins = include $sources['data'] . 'transport.plugins.php'; if (!is_array($plugins)) { $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in plugins.'); @@ -138,34 +99,76 @@ } } +$attr[xPDOTransport::RELATED_OBJECTS] = !empty($attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]); $vehicle = $builder->createVehicle($category, $attr); -/* now pack in resolvers */ -$vehicle->resolve('file', array( +// now pack in resolvers and validators +$vehicle->resolve('file', [ 'source' => $sources['source_assets'], 'target' => "return MODX_ASSETS_PATH . 'components/';", -)); -$vehicle->resolve('file', array( +]); +$vehicle->resolve('file', [ 'source' => $sources['source_core'], 'target' => "return MODX_CORE_PATH . 'components/';", -)); - +]); +/** @noinspection PhpUndefinedVariableInspection */ foreach ($BUILD_RESOLVERS as $resolver) { - if ($vehicle->resolve('php', array('source' => $sources['resolvers'] . 'resolve.' . $resolver . '.php'))) { + if ($vehicle->resolve('php', ['source' => $sources['resolvers'] . 'resolve.' . $resolver . '.php'])) { $modx->log(modX::LOG_LEVEL_INFO, 'Added resolver "' . $resolver . '" to category.'); } else { $modx->log(modX::LOG_LEVEL_INFO, 'Could not add resolver "' . $resolver . '" to category.'); } } - -flush(); $builder->putVehicle($vehicle); -$builder->setPackageAttributes(array( +// load system settings +if (defined('BUILD_SETTING_UPDATE')) { + $settings = include $sources['data'] . 'transport.settings.php'; + if (!is_array($settings)) { + $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in settings.'); + } else { + $attributes = [ + xPDOTransport::UNIQUE_KEY => 'key', + xPDOTransport::PRESERVE_KEYS => true, + xPDOTransport::UPDATE_OBJECT => BUILD_SETTING_UPDATE, + ]; + foreach ($settings as $setting) { + $vehicle = $builder->createVehicle($setting, $attributes); + $builder->putVehicle($vehicle); + } + $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($settings) . ' System Settings.'); + } + unset($settings, $setting, $attributes); +} + +// load plugins events +if (defined('BUILD_EVENT_UPDATE')) { + $events = include $sources['data'] . 'transport.events.php'; + if (!is_array($events)) { + $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in events.'); + } else { + $attributes = [ + xPDOTransport::PRESERVE_KEYS => true, + xPDOTransport::UPDATE_OBJECT => BUILD_EVENT_UPDATE, + ]; + foreach ($events as $event) { + $vehicle = $builder->createVehicle($event, $attributes); + $builder->putVehicle($vehicle); + } + $modx->log(xPDO::LOG_LEVEL_INFO, 'Packaged in ' . count($events) . ' Plugins events.'); + } + unset ($events, $event, $attributes); +} + +$builder->setPackageAttributes([ 'changelog' => file_get_contents($sources['docs'] . 'changelog.txt'), 'license' => file_get_contents($sources['docs'] . 'license.txt'), 'readme' => file_get_contents($sources['docs'] . 'readme.txt'), -)); + 'requires' => [ + 'php' => '>=7.2.0', + 'modx' => '>=3.0.0-beta', + ], +]); $modx->log(modX::LOG_LEVEL_INFO, 'Added package attributes and setup options.'); /* zip up package */ @@ -179,17 +182,16 @@ $totalTime = ($tend - $tstart); $totalTime = sprintf("%2.4f s", $totalTime); -$signature = $builder->getSignature(); $signature = $builder->getSignature(); if (defined('PKG_AUTO_INSTALL') && PKG_AUTO_INSTALL) { $sig = explode('-', $signature); $versionSignature = explode('.', $sig[1]); /** @var modTransportPackage $package */ - if (!$package = $modx->getObject('transport.modTransportPackage', array('signature' => $signature))) { - $package = $modx->newObject('transport.modTransportPackage'); + if (!$package = $modx->getObject(modTransportPackage::class, ['signature' => $signature])) { + $package = $modx->newObject(modTransportPackage::class); $package->set('signature', $signature); - $package->fromArray(array( + $package->fromArray([ 'created' => date('Y-m-d h:i:s'), 'updated' => null, 'state' => 1, @@ -200,7 +202,7 @@ 'version_major' => $versionSignature[0], 'version_minor' => !empty($versionSignature[1]) ? $versionSignature[1] : 0, 'version_patch' => !empty($versionSignature[2]) ? $versionSignature[2] : 0, - )); + ]); if (!empty($sig[2])) { $r = preg_split('/([0-9]+)/', $sig[2], -1, PREG_SPLIT_DELIM_CAPTURE); if (is_array($r) && !empty($r)) { @@ -213,8 +215,9 @@ $package->save(); } + $package->xpdo->packages['MODX\Revolution\\'] = $package->xpdo->packages['Revolution']; if ($package->install()) { - $modx->runProcessor('system/clearcache'); + $modx->runProcessor('System/ClearCache'); } } if (!empty($_GET['download'])) { diff --git a/_build/data/transport.events.php b/_build/data/transport.events.php index 075a0538..3118b992 100644 --- a/_build/data/transport.events.php +++ b/_build/data/transport.events.php @@ -1,19 +1,21 @@ $v) { - /** @var modEvent $event */ - $event = $modx->newObject('modEvent'); - $event->fromArray(array( + /** @var MODX\Revolution\modEvent $event */ + $event = $modx->newObject(MODX\Revolution\modEvent::class); + $event->fromArray([ 'name' => $v, 'service' => 6, 'groupname' => PKG_NAME, - ), '', true, true); + ], '', true, true); $events[] = $event; } diff --git a/_build/data/transport.plugins.php b/_build/data/transport.plugins.php index c25b5ddc..e2bb7cc8 100644 --- a/_build/data/transport.plugins.php +++ b/_build/data/transport.plugins.php @@ -1,21 +1,23 @@ array( +/** @var \MODX\Revolution\modX $modx */ + +$plugins = []; + +$tmp = [ + 'pdoTools' => [ 'file' => 'pdotools', 'description' => '', - 'events' => array( - 'OnMODXInit' => -100, + 'events' => [ 'OnSiteRefresh' => 0, - 'OnWebPagePrerender' => -100, - ), - ), -); + 'OnWebPagePrerender' => -101, + ], + ], +]; foreach ($tmp as $k => $v) { /** @var modplugin $plugin */ - $plugin = $modx->newObject('modPlugin'); + $plugin = $modx->newObject(MODX\Revolution\modPlugin::class); /** @noinspection PhpUndefinedVariableInspection */ $plugin->fromArray(array( 'name' => $k, @@ -29,13 +31,13 @@ $events = array(); if (!empty($v['events']) && is_array($v['events'])) { foreach ($v['events'] as $name => $priority) { - /** @var $event modPluginEvent */ - $event = $modx->newObject('modPluginEvent'); - $event->fromArray(array( + /** @var $event MODX\Revolution\modPluginEvent */ + $event = $modx->newObject(MODX\Revolution\modPluginEvent::class); + $event->fromArray([ 'event' => $name, 'priority' => $priority, 'propertyset' => 0, - ), '', true, true); + ], '', true, true); $events[] = $event; } unset($v['events']); @@ -48,4 +50,4 @@ $plugins[] = $plugin; } -return $plugins; \ No newline at end of file +return $plugins; diff --git a/_build/data/transport.settings.php b/_build/data/transport.settings.php index e8ff5fcf..29a9e17a 100644 --- a/_build/data/transport.settings.php +++ b/_build/data/transport.settings.php @@ -1,80 +1,64 @@ array( - 'xtype' => 'textfield', - 'value' => 'pdotools.pdotools', - 'key' => 'pdoTools.class', - ), - 'pdoFetch.class' => array( - 'xtype' => 'textfield', - 'value' => 'pdotools.pdofetch', - 'key' => 'pdoFetch.class', - ), - /* - 'pdoParser.class' => array( - 'xtype' => 'textfield', - 'value' => 'pdotools.pdoparser', - 'key' => 'pdoParser.class', - ), - */ - 'pdotools_class_path' => array( - 'xtype' => 'textfield', - 'value' => '{core_path}components/pdotools/model/', - 'key' => 'pdotools_class_path', - ), - 'pdofetch_class_path' => array( - 'xtype' => 'textfield', - 'value' => '{core_path}components/pdotools/model/', - 'key' => 'pdofetch_class_path', - ), - 'fenom_default' => array( +$settings = []; + +$tmp = [ + 'fenom_default' => [ 'xtype' => 'combo-boolean', 'value' => true, - ), - 'fenom_parser' => array( + ], + 'fenom_parser' => [ 'xtype' => 'combo-boolean', 'value' => false, - ), - 'fenom_php' => array( + ], + 'fenom_php' => [ 'xtype' => 'combo-boolean', 'value' => false, - ), - 'fenom_modx' => array( + ], + 'fenom_modx' => [ 'xtype' => 'combo-boolean', 'value' => false, - ), - 'fenom_options' => array( + ], + 'fenom_options' => [ 'xtype' => 'textarea', 'value' => '', - ), - 'fenom_cache' => array( + ], + 'fenom_cache' => [ 'xtype' => 'combo-boolean', 'value' => false, - ), - 'fenom_save_on_errors' => array( + ], + 'fenom_save_on_errors' => [ 'xtype' => 'combo-boolean', 'value' => false, - ), - - 'elements_path' => array( + ], + 'elements_path' => [ 'xtype' => 'textfield', 'value' => '{core_path}elements/', - ), -); + ], + 'filter_path' => [ + 'xtype' => 'combo-boolean', + 'value' => true, + ], +]; foreach ($tmp as $k => $v) { - /** @var modSystemSetting $setting */ - $setting = $modx->newObject('modSystemSetting'); - $setting->fromArray(array_merge( - array( - 'key' => PKG_NAME_LOWER . '_' . $k, - 'namespace' => PKG_NAME_LOWER, - 'area' => 'pdotools_main', - ), $v - ), '', true, true); + /** @var MODX\Revolution\modSystemSetting $setting */ + $setting = $modx->newObject(MODX\Revolution\modSystemSetting::class); + $setting->fromArray( + array_merge( + [ + 'key' => PKG_NAME_LOWER . '_' . $k, + 'namespace' => PKG_NAME_LOWER, + 'area' => 'pdotools_main', + ], + $v + ), + '', + true, + true + ); $settings[] = $setting; } diff --git a/_build/data/transport.snippets.php b/_build/data/transport.snippets.php index 4421cf81..0152938e 100644 --- a/_build/data/transport.snippets.php +++ b/_build/data/transport.snippets.php @@ -1,8 +1,10 @@ 'pdoresources', 'pdoUsers' => 'pdousers', 'pdoCrumbs' => 'pdocrumbs', @@ -13,13 +15,13 @@ 'pdoMenu' => 'pdomenu', 'pdoTitle' => 'pdotitle', 'pdoArchive' => 'pdoarchive', -); +]; foreach ($tmp as $k => $v) { - /** @var modSnippet $snippet */ - $snippet = $modx->newObject('modSnippet'); + /** @var MODX\Revolution\modSnippet $snippet */ + $snippet = $modx->newObject(MODX\Revolution\modSnippet::class); /** @noinspection PhpUndefinedVariableInspection */ - $snippet->fromArray(array( + $snippet->fromArray([ 'id' => 0, 'name' => $k, 'description' => '', @@ -27,7 +29,7 @@ 'static' => BUILD_SNIPPET_STATIC, 'source' => 1, 'static_file' => 'core/components/' . PKG_NAME_LOWER . '/elements/snippets/snippet.' . $v . '.php', - ), '', true, true); + ], '', true, true); /** @noinspection PhpIncludeInspection */ $properties = include $sources['build'] . 'properties/properties.' . $v . '.php'; diff --git a/_build/properties/properties.pdoarchive.php b/_build/properties/properties.pdoarchive.php index 1059e6c5..dac97578 100644 --- a/_build/properties/properties.pdoarchive.php +++ b/_build/properties/properties.pdoarchive.php @@ -1,184 +1,184 @@ array( +$tmp = [ + 'tpl' => [ 'type' => 'textfield', 'value' => '@INLINE
' . print_r($pdoFetch->getTime(), 1) . ''; +if ($modx->user->isAuthenticated('mgr') && (bool)$showLog) { + $modx->setPlaceholder('pdoArchiveLog', print_r($pdoFetch->getTime(), true)); } if (!empty($toPlaceholder)) { diff --git a/core/components/pdotools/elements/snippets/snippet.pdocrumbs.php b/core/components/pdotools/elements/snippets/snippet.pdocrumbs.php index 34570edb..cac8c4ec 100644 --- a/core/components/pdotools/elements/snippets/snippet.pdocrumbs.php +++ b/core/components/pdotools/elements/snippets/snippet.pdocrumbs.php @@ -1,14 +1,16 @@ getOption('pdoFetch.class', null, 'pdotools.pdofetch', true); -$path = $modx->getOption('pdofetch_class_path', null, MODX_CORE_PATH . 'components/pdotools/model/', true); -if ($pdoClass = $modx->loadClass($fqn, $path, false, true)) { - $pdoFetch = new $pdoClass($modx, $scriptProperties); -} else { - return false; -} +/** @var \MODX\Revolution\modX $modx */ + + +$modx->services['pdotools_config'] = $scriptProperties; +$pdoFetch = $modx->services->get(Fetch::class); + $pdoFetch->addTime('pdoTools loaded'); if (!isset($from) || $from == '') { @@ -23,9 +25,7 @@ if ($outputSeparator == ' → ' && $direction == 'rtl') { $outputSeparator = ' ← '; } -if ($limit == '') { - $limit = 10; -} +$limit = $limit ?: 10; // For compatibility with BreadCrumb if (!empty($maxCrumbs)) { @@ -54,15 +54,16 @@ } // -- $fastMode = !empty($fastMode); -$siteStart = $modx->getOption('siteStart', $scriptProperties, $modx->getOption('site_start')); +$siteStart = (int)$modx->getOption('siteStart', $scriptProperties, $modx->getOption('site_start')); -if (empty($showAtHome) && $modx->resource->id == $siteStart) { +if (empty($showAtHome) && $modx->resource->id === $siteStart) { return ''; } -$class = $modx->getOption('class', $scriptProperties, 'modResource'); +$class = modResource::class; +$alias = $modx->getAlias($class); // Start building "Where" expression -$where = array(); +$where = []; if (empty($showUnpublished) && empty($showUnPub)) { $where['published'] = 1; } @@ -88,16 +89,16 @@ if (!empty($customParents)) { $customParents = is_array($customParents) ? $customParents : array_map('trim', explode(',', $customParents)); - $parents = is_array($customParents) ? array_reverse($customParents) : array(); + $parents = is_array($customParents) ? array_reverse($customParents) : []; } if (empty($parents)) { - $parents = $modx->getParentIds($resource->id, $limit, array('context' => $resource->get('context_key'))); + $parents = $modx->getParentIds($resource->id, $limit, ['context' => $resource->get('context_key')]); } if (!empty($showHome)) { $parents[] = $siteStart; } -$ids = array($resource->id); +$ids = [$resource->id]; foreach ($parents as $parent) { if (!empty($parent)) { $ids[] = $parent; @@ -114,10 +115,10 @@ // Fields to select $resourceColumns = array_keys($modx->getFieldMeta($class)); -$select = array($class => implode(',', $resourceColumns)); +$select = [$alias => implode(',', $resourceColumns)]; // Add custom parameters -foreach (array('where', 'select') as $v) { +foreach (['where', 'select'] as $v) { if (!empty($scriptProperties[$v])) { $tmp = $scriptProperties[$v]; if (!is_array($tmp)) { @@ -132,17 +133,17 @@ $pdoFetch->addTime('Conditions prepared'); // Default parameters -$default = array( +$default = [ 'class' => $class, - 'where' => json_encode($where), - 'select' => json_encode($select), - 'groupby' => $class . '.id', - 'sortby' => "find_in_set(`$class`.`id`,'" . implode(',', $ids) . "')", + 'where' => $where, + 'select' => $select, + 'groupby' => $alias . '.id', + 'sortby' => "find_in_set(`$alias`.`id`,'" . implode(',', $ids) . "')", 'sortdir' => '', 'return' => 'data', 'totalVar' => 'pdocrumbs.total', 'disableConditions' => true, -); +]; // Merge all properties and run! $pdoFetch->addTime('Query parameters ready'); @@ -156,7 +157,7 @@ } foreach ($rows as $row) { - if (!empty($useWeblinkUrl) && $row['class_key'] == 'modWebLink') { + if (!empty($useWeblinkUrl) && $row['class_key'] === modWebLink::class) { $row['link'] = is_numeric(trim($row['content'], '[]~ ')) ? $pdoFetch->makeUrl((int)trim($row['content'], '[]~ '), $row) : $row['content']; @@ -199,28 +200,27 @@ if (count($output) == 1 && !empty($hideSingle)) { $pdoFetch->addTime('The only result was hidden, because the parameter "hideSingle" activated'); - $output = array(); + $output = []; } $log = ''; -if ($modx->user->hasSessionContext('mgr') && !empty($showLog)) { - $log .= '
' . print_r($pdoFetch->getTime(), 1) . ''; +if ($modx->user->isAuthenticated('mgr') && (bool)$showLog) { + $modx->setPlaceholder('pdoCrumbsLog', print_r($pdoFetch->getTime(), true)); } if (!empty($toSeparatePlaceholders)) { - $output['log'] = $log; $modx->setPlaceholders($output, $toSeparatePlaceholders); } else { $output = implode($outputSeparator, $output); if ($pdoFetch->idx >= $limit && !empty($tplMax) && !empty($output)) { $output = ($direction == 'ltr') - ? $pdoFetch->getChunk($tplMax, array(), $fastMode) . $output - : $output . $pdoFetch->getChunk($tplMax, array(), $fastMode); + ? $pdoFetch->getChunk($tplMax, [], $fastMode) . $output + : $output . $pdoFetch->getChunk($tplMax, [], $fastMode); } $output .= $log; if (!empty($tplWrapper) && (!empty($wrapIfEmpty) || !empty($output))) { - $output = $pdoFetch->getChunk($tplWrapper, array('output' => $output, 'crumbs' => $output), $fastMode); + $output = $pdoFetch->getChunk($tplWrapper, ['output' => $output, 'crumbs' => $output], $fastMode); } if (!empty($toPlaceholder)) { diff --git a/core/components/pdotools/elements/snippets/snippet.pdofield.php b/core/components/pdotools/elements/snippets/snippet.pdofield.php index ba91cdcf..145c1ab7 100644 --- a/core/components/pdotools/elements/snippets/snippet.pdofield.php +++ b/core/components/pdotools/elements/snippets/snippet.pdofield.php @@ -1,6 +1,11 @@ getOption('class', $scriptProperties, 'modResource', true); -$isResource = $class == 'modResource' || in_array($class, $modx->getDescendants('modResource')); +$class = $modx->getOption('class', $scriptProperties, modResource::class, true); +$alias = $modx->getAlias($class); +$isResource = $class === modResource::class || in_array($class, $modx->getDescendants(modResource::class)); if (empty($field)) { $field = 'pagetitle'; } $top = isset($top) ? (int)$top : 0; $topLevel = isset($topLevel) ? (int)$topLevel : 0; -if (!empty($options)) { +if (!empty($options) && is_string($options)) { $options = trim($options); if ($options[0] == '{') { $tmp = json_decode($options, true); if (is_array($tmp)) { - extract($tmp); + extract($tmp, EXTR_OVERWRITE); $scriptProperties = array_merge($scriptProperties, $tmp); } } else { @@ -34,7 +40,7 @@ if (!empty($modx->resource)) { $id = $modx->resource->id; } else { - return 'You must specify an id of ' . $class; + return 'You must specify an id of ' . $alias; } } if (!isset($context)) { @@ -100,19 +106,13 @@ } } -/** @var pdoFetch $pdoFetch */ -$fqn = $modx->getOption('pdoFetch.class', null, 'pdotools.pdofetch', true); -$path = $modx->getOption('pdofetch_class_path', null, MODX_CORE_PATH . 'components/pdotools/model/', true); -if ($pdoClass = $modx->loadClass($fqn, $path, false, true)) { - $pdoFetch = new $pdoClass($modx, $scriptProperties); -} else { - return false; -} +$modx->services['pdotools_config'] = $scriptProperties; +$pdoFetch = $modx->services->get(Fetch::class); $pdoFetch->addTime('pdoTools loaded'); -$where = [$class . '.id' => $id]; +$where = [$alias . '.id' => $id]; // Add custom parameters -foreach (array('where') as $v) { +foreach (['where'] as $v) { if (!empty($scriptProperties[$v])) { $tmp = $scriptProperties[$v]; if (!is_array($tmp)) { @@ -130,17 +130,17 @@ $resourceColumns = array_keys($modx->getFieldMeta($class)); $field = strtolower($field); if (in_array($field, $resourceColumns)) { - $scriptProperties['select'] = [$class => $field]; + $scriptProperties['select'] = [$alias => $field]; $scriptProperties['includeTVs'] = ''; } elseif ($isResource) { - $scriptProperties['select'] = [$class => 'id']; + $scriptProperties['select'] = [$alias => 'id']; $scriptProperties['includeTVs'] = $field; } // Additional default field if (!empty($default)) { $default = strtolower($default); if (in_array($default, $resourceColumns)) { - $scriptProperties['select'][$class] .= ',' . $default; + $scriptProperties['select'][$alias] .= ',' . $default; } elseif ($isResource) { $scriptProperties['includeTVs'] = empty($scriptProperties['includeTVs']) ? $default @@ -149,7 +149,7 @@ } $scriptProperties['disableConditions'] = true; -if ($row = $pdoFetch->getObject($class, $where, $scriptProperties)) { +if ($row = $pdoFetch->getArray($class, $where, $scriptProperties)) { foreach ($row as $k => $v) { if (strtolower($k) == $field && $v != '') { $output = $v; @@ -171,4 +171,4 @@ $modx->setPlaceholder($toPlaceholder, $output); } else { return $output; -} \ No newline at end of file +} diff --git a/core/components/pdotools/elements/snippets/snippet.pdomenu.php b/core/components/pdotools/elements/snippets/snippet.pdomenu.php index f0f23b35..be37520b 100644 --- a/core/components/pdotools/elements/snippets/snippet.pdomenu.php +++ b/core/components/pdotools/elements/snippets/snippet.pdomenu.php @@ -1,6 +1,11 @@ getService('pdoFetch'); + /** @var Fetch $pdoFetch */ + $pdoFetch = $modx->services->get('pdofetch'); foreach ($contexts as $ctx) { - $parents = array_merge($parents, $pdoFetch->getChildIds('modResource', 0, $scriptProperties['depth'], array('context' => $ctx))); + $parents = array_merge($parents, $pdoFetch->getChildIds(modResource::class, 0, $scriptProperties['depth'], ['context' => $ctx])); } } else { foreach ($contexts as $ctx) { - $parents = array_merge($parents, $modx->getChildIds(0, $scriptProperties['depth'], array('context' => $ctx))); + $parents = array_merge($parents, $modx->getChildIds(0, $scriptProperties['depth'], ['context' => $ctx])); } } $scriptProperties['parents'] = !empty($parents) ? implode(',', $parents) : '+0'; @@ -66,7 +71,7 @@ $scriptProperties['displayStart'] = 0; } else { $parents = array_map('trim', explode(',', $scriptProperties['parents'])); - $parents_in = $parents_out = array(); + $parents_in = $parents_out = []; foreach ($parents as $v) { if (!is_numeric($v)) { continue; @@ -106,7 +111,7 @@ $scriptProperties['showHidden'] = $ignoreHidden; } -$wfTemplates = array( +$wfTemplates = [ 'outerTpl' => 'tplOuter', 'rowTpl' => 'tpl', 'parentRowTpl' => 'tplParentRow', @@ -118,7 +123,7 @@ 'activeParentRowTpl' => 'tplParentRowActive', 'categoryFoldersTpl' => 'tplCategoryFolder', 'startItemTpl' => 'tplStart', -); +]; foreach ($wfTemplates as $k => $v) { if (isset(${$k})) { $scriptProperties[$v] = ${$k}; @@ -126,15 +131,10 @@ } //--- -/** @var pdoMenu $pdoMenu */ -$fqn = $modx->getOption('pdoMenu.class', null, 'pdotools.pdomenu', true); -$path = $modx->getOption('pdomenu_class_path', null, MODX_CORE_PATH . 'components/pdotools/model/', true); -if ($pdoClass = $modx->loadClass($fqn, $path, false, true)) { - $pdoMenu = new $pdoClass($modx, $scriptProperties); -} else { - return false; -} -$pdoMenu->pdoTools->addTime('pdoTools loaded'); +/** @var MenuBuilder $menuBuilder */ +$modx->services['pdotools_config'] = $scriptProperties; +$menuBuilder = $modx->services->get(MenuBuilder::class); +$menuBuilder->pdoTools->addTime('MenuBuilder loaded'); $cache = !empty($cache) || (!$modx->user->id && !empty($cacheAnonymous)); if (empty($scriptProperties['cache_key'])) { @@ -142,17 +142,17 @@ } $output = ''; -$tree = array(); +$tree = []; if ($cache) { - $tree = $pdoMenu->pdoTools->getCache($scriptProperties); + $tree = $menuBuilder->pdoTools->getCache($scriptProperties); } if (empty($tree)) { - $data = $pdoMenu->pdoTools->run(); - $data = $pdoMenu->pdoTools->buildTree($data, 'id', 'parent', $specified_parents); - $tree = array(); + $data = $menuBuilder->pdoTools->run(); + $data = $menuBuilder->pdoTools->buildTree($data, 'id', 'parent', $specified_parents); + $tree = []; foreach ($data as $k => $v) { if (empty($v['id'])) { - if (!in_array($k, $specified_parents) && !$pdoMenu->checkResource($k)) { + if (!in_array($k, $specified_parents) && !$menuBuilder->checkResource($k)) { continue; } else { $tree = array_merge($tree, $v['children']); @@ -162,22 +162,22 @@ } } if ($cache) { - $pdoMenu->pdoTools->setCache($tree, $scriptProperties); + $menuBuilder->pdoTools->setCache($tree, $scriptProperties); } } if (isset($return) && $return === 'data') { return $tree; } if (!empty($tree)) { - $output = $pdoMenu->templateTree($tree); + $output = $menuBuilder->templateTree($tree); } -if ($modx->user->hasSessionContext('mgr') && !empty($showLog)) { - $output .= '
' . print_r($pdoMenu->pdoTools->getTime(), 1) . ''; +if ($modx->user->isAuthenticated('mgr') && !empty($showLog)) { + $modx->setPlaceholder('pdoMenuLog', print_r($menuBuilder->pdoTools->getTime(), true)); } if (!empty($toPlaceholder)) { $modx->setPlaceholder($toPlaceholder, $output); } else { return $output; -} \ No newline at end of file +} diff --git a/core/components/pdotools/elements/snippets/snippet.pdoneighbors.php b/core/components/pdotools/elements/snippets/snippet.pdoneighbors.php index 20bada92..f2003b56 100644 --- a/core/components/pdotools/elements/snippets/snippet.pdoneighbors.php +++ b/core/components/pdotools/elements/snippets/snippet.pdoneighbors.php @@ -1,14 +1,14 @@ getOption('pdoFetch.class', null, 'pdotools.pdofetch', true); -$path = $modx->getOption('pdofetch_class_path', null, MODX_CORE_PATH . 'components/pdotools/model/', true); -if ($pdoClass = $modx->loadClass($fqn, $path, false, true)) { - $pdoFetch = new $pdoClass($modx, $scriptProperties); -} else { - return false; -} + +$modx->services['pdotools_config'] = $scriptProperties; +$pdoFetch = $modx->services->get(Fetch::class); $pdoFetch->addTime('pdoTools loaded'); if (empty($id)) { @@ -22,7 +22,8 @@ } $fastMode = !empty($fastMode); -$class = 'modResource'; +$class = modResource::class; +$alias = $modx->getAlias($class); $resource = ($id == $modx->resource->id) ? $modx->resource : $modx->getObject($class, $id); @@ -44,10 +45,10 @@ unset($parents[$key]); } $params['parents'] = implode(',', $parents); - $ids = $pdoFetch->getCollection('modResource', [], $params); + $ids = $pdoFetch->getCollection(modResource::class, [], $params); unset($scriptProperties['parents']); } else { - $ids = $pdoFetch->getCollection('modResource', ['parent' => $resource->parent], $params); + $ids = $pdoFetch->getCollection(modResource::class, ['parent' => $resource->parent], $params); } $found = false; @@ -81,7 +82,7 @@ $pdoFetch->addTime('Found ids of neighbors: ' . implode(',', $ids)); // Query conditions -$where = [$class . '.id:IN' => $ids]; +$where = [$alias . '.id:IN' => $ids]; // Fields to select $resourceColumns = array_keys($modx->getFieldMeta($class)); @@ -89,7 +90,7 @@ $key = array_search('content', $resourceColumns); unset($resourceColumns[$key]); } -$select = [$class => implode(',', $resourceColumns)]; +$select = [$alias => implode(',', $resourceColumns)]; // Add custom parameters foreach (['where', 'select'] as $v) { @@ -109,8 +110,8 @@ // Default parameters $default = [ 'class' => $class, - 'where' => json_encode($where), - 'select' => json_encode($select), + 'where' => $where, + 'select' => $select, //'groupby' => $class.'.id', 'sortby' => $class . '.menuindex', 'sortdir' => 'ASC', @@ -136,7 +137,7 @@ if (empty($row['menutitle'])) { $row['menutitle'] = $row['pagetitle']; } - if (!empty($useWeblinkUrl) && $row['class_key'] == 'modWebLink') { + if (!empty($useWeblinkUrl) && $row['class_key'] === modWebLink::class) { $row['link'] = is_numeric(trim($row['content'], '[]~ ')) ? $pdoFetch->makeUrl((int)trim($row['content'], '[]~ '), $row) : $row['content']; diff --git a/core/components/pdotools/elements/snippets/snippet.pdopage.php b/core/components/pdotools/elements/snippets/snippet.pdopage.php index cdb18c3e..512388e6 100644 --- a/core/components/pdotools/elements/snippets/snippet.pdopage.php +++ b/core/components/pdotools/elements/snippets/snippet.pdopage.php @@ -1,6 +1,11 @@ getOption('pdoPage.class', null, 'pdotools.pdopage', true); -$path = $modx->getOption('pdopage_class_path', null, MODX_CORE_PATH . 'components/pdotools/model/', true); -if ($pdoClass = $modx->loadClass($fqn, $path, false, true)) { - $pdoPage = new $pdoClass($modx, $scriptProperties); -} else { - return false; -} -$pdoPage->pdoTools->addTime('pdoTools loaded'); +$modx->services['pdotools_config'] = $scriptProperties; +/** @var Paginator $paginator */ +$paginator = $modx->services->get(Paginator::class); +$paginator->pdoTools->addTime('pdoTools loaded'); // Script and styles if (!$isAjax && !empty($scriptProperties['ajaxMode'])) { - $pdoPage->loadJsCss(); + $paginator->loadJsCss(); } // Removing of default scripts and styles so they do not overwrote nested snippet parameters -if ($snippet = $modx->getObject('modSnippet', ['name' => 'pdoPage'])) { +if ($snippet = $modx->getObject(modSnippet::class, ['name' => 'pdoPage'])) { $properties = $snippet->get('properties'); if ($scriptProperties['frontend_js'] == $properties['frontend_js']['value']) { unset($scriptProperties['frontend_js']); @@ -98,14 +98,13 @@ // Page if (isset($_REQUEST[$pageVarKey]) && $strictMode && (!is_numeric($_REQUEST[$pageVarKey]) || ($_REQUEST[$pageVarKey] <= 1 && !$isAjax))) { - return $pdoPage->redirectToFirst($isAjax); + return $paginator->redirectToFirst($isAjax); } elseif (!empty($_REQUEST[$pageVarKey])) { $page = (integer)$_REQUEST[$pageVarKey]; } $scriptProperties['page'] = $page; $scriptProperties['request'] = $_REQUEST; $scriptProperties['setTotal'] = true; - // Limit if (isset($_REQUEST['limit'])) { if (is_numeric($_REQUEST['limit']) && abs($_REQUEST['limit']) > 0) { @@ -113,7 +112,7 @@ } elseif ($strictMode) { unset($_GET['limit']); - return $pdoPage->redirectToFirst($isAjax); + return $paginator->redirectToFirst($isAjax); } } if (!empty($maxLimit) && !empty($scriptProperties['limit']) && $scriptProperties['limit'] > $maxLimit) { @@ -121,26 +120,27 @@ } // Offset -$offset = !empty($scriptProperties['offset']) && $scriptProperties['offset'] > 0 +$_offset = !empty($scriptProperties['offset']) && $scriptProperties['offset'] > 0 ? (int)$scriptProperties['offset'] : 0; $scriptProperties['offset'] = $page > 1 - ? $scriptProperties['limit'] * ($page - 1) + $offset - : $offset; + ? $scriptProperties['limit'] * ($page - 1) + $_offset + : $_offset; if (!empty($scriptProperties['offset']) && empty($scriptProperties['limit'])) { $scriptProperties['limit'] = 10000000; } $cache = !empty($cache) || (!$modx->user->id && !empty($cacheAnonymous)); -$url = $pdoPage->getBaseUrl(); +$charset = $modx->getOption('modx_charset', null, 'UTF-8'); +$url = htmlentities($paginator->getBaseUrl(), ENT_QUOTES, $charset); $output = $pagination = $total = $pageCount = ''; $data = $cache - ? $pdoPage->pdoTools->getCache($scriptProperties) + ? $paginator->pdoTools->getCache($scriptProperties) : []; if (empty($data)) { - $output = $pdoPage->pdoTools->runSnippet($scriptProperties['element'], $scriptProperties); + $output = $paginator->pdoTools->runSnippet('!' . $scriptProperties['element'], $scriptProperties); if ($output === false) { return ''; } elseif (!empty($toPlaceholder)) { @@ -149,38 +149,38 @@ // Pagination $total = (int)$modx->getPlaceholder($totalVar); - $pageCount = !empty($scriptProperties['limit']) && $total > $offset - ? ceil(($total - $offset) / $scriptProperties['limit']) + $pageCount = !empty($scriptProperties['limit']) && $total > $_offset + ? ceil(($total - $_offset) / $scriptProperties['limit']) : 0; // Redirect to start if somebody specified incorrect page if ($page > 1 && $page > $pageCount && $strictMode) { - return $pdoPage->redirectToFirst($isAjax); + return $paginator->redirectToFirst($isAjax); } if (!empty($pageCount) && $pageCount > 1) { $pagination = [ 'first' => $page > 1 && !empty($tplPageFirst) - ? $pdoPage->makePageLink($url, 1, $tplPageFirst) + ? $paginator->makePageLink($url, 1, $tplPageFirst) : '', 'prev' => $page > 1 && !empty($tplPagePrev) - ? $pdoPage->makePageLink($url, $page - 1, $tplPagePrev) + ? $paginator->makePageLink($url, $page - 1, $tplPagePrev) : '', 'pages' => $pageLimit >= 7 && empty($disableModernPagination) - ? $pdoPage->buildModernPagination($page, $pageCount, $url) - : $pdoPage->buildClassicPagination($page, $pageCount, $url), + ? $paginator->buildModernPagination($page, $pageCount, $url) + : $paginator->buildClassicPagination($page, $pageCount, $url), 'next' => $page < $pageCount && !empty($tplPageNext) - ? $pdoPage->makePageLink($url, $page + 1, $tplPageNext) + ? $paginator->makePageLink($url, $page + 1, $tplPageNext) : '', 'last' => $page < $pageCount && !empty($tplPageLast) - ? $pdoPage->makePageLink($url, $pageCount, $tplPageLast) + ? $paginator->makePageLink($url, $pageCount, $tplPageLast) : '', ]; if (!empty($pageCount)) { foreach (['first', 'prev', 'next', 'last'] as $v) { - $tpl = 'tplPage' . ucfirst($v) . 'Empty'; - if (!empty(${$tpl}) && empty($pagination[$v])) { - $pagination[$v] = $pdoPage->pdoTools->getChunk(${$tpl}); + $_tpl = 'tplPage' . ucfirst($v) . 'Empty'; + if (!empty(${$_tpl}) && empty($pagination[$v])) { + $pagination[$v] = $paginator->pdoTools->getChunk(${$_tpl}); } } } @@ -190,7 +190,7 @@ 'prev' => '', 'pages' => '', 'next' => '', - 'last' => '' + 'last' => '', ]; } @@ -199,33 +199,33 @@ $pageVarKey => $page, $pageCountVar => $pageCount, $pageNavVar => !empty($tplPageWrapper) - ? $pdoPage->pdoTools->getChunk($tplPageWrapper, $pagination) - : $pdoPage->pdoTools->parseChunk('', $pagination), + ? $paginator->pdoTools->getChunk($tplPageWrapper, $pagination) + : $paginator->pdoTools->parseChunk('', $pagination), $totalVar => $total, ]; if ($cache) { - $pdoPage->pdoTools->setCache($data, $scriptProperties); + $paginator->pdoTools->setCache($data, $scriptProperties); } } - -if ($modx->user->hasSessionContext('mgr') && !empty($showLog)) { - $data['output'] .= '
' . print_r($pdoPage->pdoTools->getTime(), 1) . ''; +/** @var bool $showLog */ +if ($modx->user->isAuthenticated('mgr') && (bool)$showLog) { + $modx->setPlaceholder('pdoPageLog', print_r($paginator->pdoTools->getTime(), true)); } if ($isAjax) { - if ($pageNavVar != 'pagination') { + if ($pageNavVar !== 'pagination') { $data['pagination'] = $data[$pageNavVar]; unset($data[$pageNavVar]); } - if ($pageCountVar != 'pages') { + if ($pageCountVar !== 'pages') { $data['pages'] = (int)$data[$pageCountVar]; unset($data[$pageCountVar]); } - if ($pageVarKey != 'page') { + if ($pageVarKey !== 'page') { $data['page'] = (int)$data[$pageVarKey]; unset($data[$pageVarKey]); } - if ($totalVar != 'total') { + if ($totalVar !== 'total') { $data['total'] = (int)$data[$totalVar]; unset($data[$totalVar]); } @@ -236,31 +236,30 @@ @session_write_close(); exit(json_encode($data)); -} else { - if (!empty($setMeta)) { - $charset = $modx->getOption('modx_charset', null, 'UTF-8'); - $canurl = $pdoPage->pdoTools->config['scheme'] !== 'full' - ? rtrim($modx->getOption('site_url'), '/') . '/' . ltrim($url, '/') - : $url; - $modx->regClientStartupHTMLBlock(''); - if ($data[$pageVarKey] > 1) { - $prevUrl = $pdoPage->makePageLink($canurl, $data[$pageVarKey] - 1); - $modx->regClientStartupHTMLBlock( - '' - ); - } - if ($data[$pageVarKey] < $data[$pageCountVar]) { - $nextUrl = $pdoPage->makePageLink($canurl, $data[$pageVarKey] + 1); - $modx->regClientStartupHTMLBlock( - '' - ); - } - } +} - $modx->setPlaceholders($data, $plPrefix); - if (!empty($toPlaceholder)) { - $modx->setPlaceholder($toPlaceholder, $data['output']); - } else { - return $data['output']; +if (!empty($setMeta)) { + $canurl = $paginator->pdoTools->config('scheme') !== 'full' + ? $paginator->getCanonicalUrl($url) + : $url; + $modx->regClientStartupHTMLBlock(''); + if ($data[$pageVarKey] > 1) { + $prevUrl = $paginator->makePageLink($canurl, $data[$pageVarKey] - 1); + $modx->regClientStartupHTMLBlock( + '' + ); } + if ($data[$pageVarKey] < $data[$pageCountVar]) { + $nextUrl = $paginator->makePageLink($canurl, $data[$pageVarKey] + 1); + $modx->regClientStartupHTMLBlock( + '' + ); + } +} + +$modx->setPlaceholders($data, $plPrefix); +if (!empty($toPlaceholder)) { + $modx->setPlaceholder($toPlaceholder, $data['output']); +} else { + return $data['output']; } diff --git a/core/components/pdotools/elements/snippets/snippet.pdoresources.php b/core/components/pdotools/elements/snippets/snippet.pdoresources.php index 9a906f17..24cd583f 100644 --- a/core/components/pdotools/elements/snippets/snippet.pdoresources.php +++ b/core/components/pdotools/elements/snippets/snippet.pdoresources.php @@ -1,6 +1,11 @@ resource->id; } @@ -15,8 +20,7 @@ $additionalPlaceholders = $properties = []; if (isset($this) && $this instanceof modSnippet && $this->get('properties')) { $properties = $this->get('properties'); -} -elseif ($snippet = $modx->getObject('modSnippet', ['name' => 'pdoResources'])) { +} elseif ($snippet = $modx->getObject(modSnippet::class, ['name' => 'pdoResources'])) { $properties = $snippet->get('properties'); } if (!empty($properties)) { @@ -28,25 +32,17 @@ } $scriptProperties['additionalPlaceholders'] = $additionalPlaceholders; -/** @var pdoFetch $pdoFetch */ -$fqn = $modx->getOption('pdoFetch.class', null, 'pdotools.pdofetch', true); -$path = $modx->getOption('pdofetch_class_path', null, MODX_CORE_PATH . 'components/pdotools/model/', true); -if ($pdoClass = $modx->loadClass($fqn, $path, false, true)) { - $pdoFetch = new $pdoClass($modx, $scriptProperties); -} else { - return false; -} +$modx->services['pdotools_config'] = $scriptProperties; +$pdoFetch = $modx->services->get(Fetch::class); $pdoFetch->addTime('pdoTools loaded'); $output = $pdoFetch->run(); -$log = ''; -if ($modx->user->hasSessionContext('mgr') && !empty($showLog)) { - $log .= '
' . print_r($pdoFetch->getTime(), 1) . ''; +if ($modx->user->isAuthenticated('mgr') && !empty($showLog)) { + $modx->setPlaceholder('pdoResourcesLog', print_r($pdoFetch->getTime(), true)); } // Return output if (!empty($returnIds)) { - $modx->setPlaceholder('pdoResources.log', $log); if (!empty($toPlaceholder)) { $modx->setPlaceholder($toPlaceholder, $output); } else { @@ -55,14 +51,11 @@ } elseif ($return === 'data') { return $output; } elseif (!empty($toSeparatePlaceholders)) { - $output['log'] = $log; $modx->setPlaceholders($output, $toSeparatePlaceholders); } else { - $output .= $log; - if (!empty($tplWrapper) && (!empty($wrapIfEmpty) || !empty($output))) { $output = $pdoFetch->getChunk($tplWrapper, array_merge($additionalPlaceholders, ['output' => $output]), - $pdoFetch->config['fastMode']); + $pdoFetch->config('fastMode')); } if (!empty($toPlaceholder)) { diff --git a/core/components/pdotools/elements/snippets/snippet.pdositemap.php b/core/components/pdotools/elements/snippets/snippet.pdositemap.php index 53097b56..0a36d95d 100644 --- a/core/components/pdotools/elements/snippets/snippet.pdositemap.php +++ b/core/components/pdotools/elements/snippets/snippet.pdositemap.php @@ -1,13 +1,14 @@ getOption('pdoFetch.class', null, 'pdotools.pdofetch', true); -$path = $modx->getOption('pdofetch_class_path', null, MODX_CORE_PATH . 'components/pdotools/model/', true); -if ($pdoClass = $modx->loadClass($fqn, $path, false, true)) { - $pdoFetch = new $pdoClass($modx, $scriptProperties); -} else { - return false; -} +/** @var \MODX\Revolution\modX $modx */ + +$modx->services['pdotools_config'] = []; +$pdoFetch = $modx->services->get(Fetch::class); $pdoFetch->addTime('pdoTools loaded'); // Default variables @@ -98,21 +99,22 @@ //--- -$class = 'modResource'; +$class = modResource::class; +$alias = $modx->getAlias($class); $where = []; if (empty($showHidden)) { $where[] = [ - $class . '.hidemenu' => 0, - 'OR:' . $class . '.class_key:IN' => ['Ticket', 'Article'], + $alias . '.hidemenu' => 0, + 'OR:' . $alias . '.class_key:IN' => ['Ticket', 'Article'], ]; } if (empty($context)) { $scriptProperties['context'] = $modx->context->key; } -$select = [$class => 'id,editedon,createdon,context_key,class_key,uri']; +$select = [$alias => 'id,editedon,createdon,context_key,class_key,uri']; if (!empty($useWeblinkUrl)) { - $select[$class] .= ',content'; + $select[$alias] .= ',content'; } // Add custom parameters foreach (['where', 'select'] as $v) { @@ -132,9 +134,9 @@ // Default parameters $default = [ 'class' => $class, - 'where' => json_encode($where), - 'select' => json_encode($select), - 'sortby' => "{$class}.parent ASC, {$class}.menuindex", + 'where' => $where, + 'select' => $select, + 'sortby' => "{$alias}.parent ASC, {$alias}.menuindex", 'sortdir' => 'ASC', 'return' => 'data', 'scheme' => 'full', @@ -155,7 +157,7 @@ $data = $urls = []; $rows = $pdoFetch->run(); foreach ($rows as $row) { - if (!empty($useWeblinkUrl) && $row['class_key'] == 'modWebLink') { + if (!empty($useWeblinkUrl) && $row['class_key'] == modWebLink::class) { $row['url'] = is_numeric(trim($row['content'], '[]~ ')) ? $pdoFetch->makeUrl((int)trim($row['content'], '[]~ '), $row) : $row['content']; @@ -221,8 +223,8 @@ ]); $pdoFetch->addTime('Rows wrapped'); - if ($modx->user->hasSessionContext('mgr') && !empty($showLog)) { - $output .= '
' . print_r($pdoFetch->getTime(), 1) . ''; + if ($modx->user->isAuthenticated('mgr') && !empty($showLog)) { + $modx->setPlaceholder('pdoSitemapLog', print_r($pdoFetch->getTime(), true)); } } if (!empty($forceXML)) { @@ -231,4 +233,4 @@ exit($output); } else { return $output; -} \ No newline at end of file +} diff --git a/core/components/pdotools/elements/snippets/snippet.pdotitle.php b/core/components/pdotools/elements/snippets/snippet.pdotitle.php index 7a56f04b..ed2d645a 100644 --- a/core/components/pdotools/elements/snippets/snippet.pdotitle.php +++ b/core/components/pdotools/elements/snippets/snippet.pdotitle.php @@ -1,6 +1,11 @@ getOption('pdoTools.class', null, 'pdotools.pdotools', true); -$path = $modx->getOption('pdotools_class_path', null, MODX_CORE_PATH . 'components/pdotools/model/', true); -if ($pdoClass = $modx->loadClass($fqn, $path, false, true)) { - $pdoTools = new $pdoClass($modx, $scriptProperties); -} else { - return false; -} +/** @var CoreTools $pdoTools */ +$modx->services['pdotools_config'] = $scriptProperties; +$pdoTools = $modx->services->get(CoreTools::class); $modx->lexicon->load('pdotools:pdopage'); /** @var modResource $resource */ @@ -75,7 +75,7 @@ $cacheOptions = ['cache_key' => $modx->getOption('cache_resource_key', null, 'resource')]; $crumbs = ''; if (empty($cache) || !$crumbs = $modx->cacheManager->get($cacheKey, $cacheOptions)) { - $crumbs = $pdoTools->runSnippet('pdoCrumbs', array_merge( + $crumbs = $pdoTools->runSnippet('!pdoCrumbs', array_merge( [ 'to' => $resource->id, 'outputSeparator' => $outputSeparator, @@ -108,4 +108,4 @@ true); } -return implode($outputSeparator, $title); \ No newline at end of file +return implode($outputSeparator, $title); diff --git a/core/components/pdotools/elements/snippets/snippet.pdousers.php b/core/components/pdotools/elements/snippets/snippet.pdousers.php index b0893068..b889203c 100644 --- a/core/components/pdotools/elements/snippets/snippet.pdousers.php +++ b/core/components/pdotools/elements/snippets/snippet.pdousers.php @@ -1,37 +1,43 @@ getOption('pdoFetch.class', null, 'pdotools.pdofetch', true); -$path = $modx->getOption('pdofetch_class_path', null, MODX_CORE_PATH . 'components/pdotools/model/', true); -if ($pdoClass = $modx->loadClass($fqn, $path, false, true)) { - $pdoFetch = new $pdoClass($modx, $scriptProperties); -} else { - return false; -} +$modx->services['pdotools_config'] = $scriptProperties; +$pdoFetch = $modx->services->get(Fetch::class); $pdoFetch->addTime('pdoTools loaded'); -$class = 'modUser'; -$profile = 'modUserProfile'; -$member = 'modUserGroupMember'; +$class = modUser::class; +$alias_class = $modx->getAlias($class); +$profile = modUserProfile::class; +$alias_profile = $modx->getAlias($profile); +$member = modUserGroupMember::class; +$alias_member = $modx->getAlias($member); // Start building "Where" expression $where = []; if (empty($showInactive)) { - $where[$class . '.active'] = 1; + $where[$alias_class . '.active'] = 1; } if (empty($showBlocked)) { - $where[$profile . '.blocked'] = 0; + $where[$alias_profile . '.blocked'] = 0; } // Add users profiles and groups $innerJoin = [ - $profile => ['alias' => $profile, 'on' => "$class.id = $profile.internalKey"], + $profile => ['class' => $profile, 'alias' => $alias_profile, 'on' => "$alias_class.id = $alias_profile.internalKey"], ]; // Filter by users, groups and roles @@ -39,17 +45,17 @@ 'users' => [ 'class' => $class, 'name' => 'username', - 'join' => $class . '.id', + 'join' => $alias_class . '.id', ], 'groups' => [ - 'class' => 'modUserGroup', + 'class' => modUserGroup::class, 'name' => 'name', - 'join' => $member . '.user_group', + 'join' => $alias_member . '.user_group', ], 'roles' => [ - 'class' => 'modUserGroupRole', + 'class' => modUserGroupRole::class, 'name' => 'name', - 'join' => $member . '.role', + 'join' => $alias_member . '.role', ], ]; foreach ($tmp as $k => $p) { @@ -99,7 +105,7 @@ } if (!empty($groups_in) || !empty($groups_out) || !empty($roles_in) || !empty($roles_out)) { - $innerJoin[$member] = ['alias' => $member, 'on' => "$class.id = $member.member"]; + $innerJoin[$alias_member] = ['class' => $member, 'alias' => $alias_member, 'on' => "$alias_class.id = $alias_member.member"]; } // Fields to select @@ -125,19 +131,19 @@ $default = [ 'class' => $class, - 'innerJoin' => json_encode($innerJoin), - 'where' => json_encode($where), - 'select' => json_encode($select), - 'groupby' => $class . '.id', - 'sortby' => $class . '.id', + 'innerJoin' => $innerJoin, + 'where' => $where, + 'select' => $select, + 'groupby' => $alias_class . '.id', + 'sortby' => $alias_class . '.id', 'sortdir' => 'ASC', 'fastMode' => false, 'return' => $return, 'disableConditions' => true, ]; -if (!empty($users_in) && (empty($scriptProperties['sortby']) || $scriptProperties['sortby'] == $class . '.id')) { - $scriptProperties['sortby'] = "find_in_set(`$class`.`id`,'" . implode(',', $users_in) . "')"; +if (!empty($users_in) && (empty($scriptProperties['sortby']) || $scriptProperties['sortby'] == $alias_class . '.id')) { + $scriptProperties['sortby'] = "find_in_set(`$alias_class`.`id`,'" . implode(',', $users_in) . "')"; $scriptProperties['sortdir'] = ''; } @@ -147,13 +153,12 @@ $output = $pdoFetch->run(); $log = ''; -if ($modx->user->hasSessionContext('mgr') && !empty($showLog)) { - $log .= '
' . print_r($pdoFetch->getTime(), 1) . ''; +if ($modx->user->isAuthenticated('mgr') && !empty($showLog)) { + $modx->setPlaceholder('pdoUsersLog', print_r($pdoFetch->getTime(), true)); } // Return output if (!empty($returnIds)) { - $modx->setPlaceholder('pdoUsers.log', $log); if (!empty($toPlaceholder)) { $modx->setPlaceholder($toPlaceholder, $output); } else { @@ -162,13 +167,10 @@ } elseif ($return === 'data') { return $output; } elseif (!empty($toSeparatePlaceholders)) { - $output['log'] = $log; $modx->setPlaceholders($output, $toSeparatePlaceholders); } else { - $output .= $log; - if (!empty($tplWrapper) && (!empty($wrapIfEmpty) || !empty($output))) { - $output = $pdoFetch->getChunk($tplWrapper, ['output' => $output], $pdoFetch->config['fastMode']); + $output = $pdoFetch->getChunk($tplWrapper, ['output' => $output], $pdoFetch->config('fastMode')); } if (!empty($toPlaceholder)) { @@ -176,4 +178,4 @@ } else { return $output; } -} \ No newline at end of file +} diff --git a/core/components/pdotools/lexicon/de/default.inc.php b/core/components/pdotools/lexicon/de/default.inc.php index 48b62392..9e268fb9 100644 --- a/core/components/pdotools/lexicon/de/default.inc.php +++ b/core/components/pdotools/lexicon/de/default.inc.php @@ -10,23 +10,6 @@ $_lang['area_pdotools_main'] = 'Grundeinstellungen'; -$_lang['setting_pdoTools.class'] = 'FQN von pdoTools'; -$_lang['setting_pdoTools.class_desc'] = 'FQN (Fully Qualified Name) der pdoTools-Klasse. Der Pfad für das Laden der Klasse wird in der Systemeinstellung "pdotools_class_path" festgelegt.'; -$_lang['setting_pdotools_class_path'] = 'Basispfad der pdoTools-Klasse'; -$_lang['setting_pdotools_class_path_desc'] = 'Basispfad der pdoTools-Klasse, aus dem sie bei Verwendung des FQN (Fully Qualified Name) geladen wird.'; - -$_lang['setting_pdoFetch.class'] = 'FQN von pdoFetch'; -$_lang['setting_pdoFetch.class_desc'] = 'FQN (Fully Qualified Name) der pdoFetch-Klasse. Der Pfad für das Laden der Klasse wird in der Systemeinstellung "pdofetch_class_path" festgelegt.'; -$_lang['setting_pdofetch_class_path'] = 'Basispfad der pdoFetch-Klasse'; -$_lang['setting_pdofetch_class_path_desc'] = 'Basispfad der pdoFetch Klasse, aus dem sie bei Verwendung des FQN (Fully Qualified Name) geladen wird.'; - -$_lang['setting_pdoParser.class'] = 'FQN von pdoParser'; -$_lang['setting_pdoParser.class_desc'] = 'FQN (Fully Qualified Name) der pdoParser-Klasse. Der Pfad für das Laden der Klasse wird in der Systemeinstellung "parser_class_path" festgelegt.'; -$_lang['setting_parser_class'] = 'Parser-Klasse'; -$_lang['setting_parser_class_desc'] = 'Parser-Klasse, die verwendet wird, um die MODX-Tags zu verarbeiten.'; -$_lang['setting_parser_class_path'] = 'Pfad zum Parser'; -$_lang['setting_parser_class_path_desc'] = 'Basispfad der Parser-Klasse, aus dem sie bei Verwendung des FQN (Fully Qualified Name) geladen wird.'; - $_lang['setting_pdotools_elements_path'] = 'Pfad zu den Elementen'; $_lang['setting_pdotools_elements_path_desc'] = 'Verzeichnis mit Datei-Elementen, die mittels @FILE-Bindung geladen werden können.'; $_lang['setting_pdotools_fenom_default'] = 'Fenom für Chunks verwenden'; diff --git a/core/components/pdotools/lexicon/en/default.inc.php b/core/components/pdotools/lexicon/en/default.inc.php index 4f34a9e3..a730f839 100644 --- a/core/components/pdotools/lexicon/en/default.inc.php +++ b/core/components/pdotools/lexicon/en/default.inc.php @@ -10,23 +10,6 @@ $_lang['area_pdotools_main'] = 'Main'; -$_lang['setting_pdoTools.class'] = 'FQN of pdoTools'; -$_lang['setting_pdoTools.class_desc'] = 'Path for loading class from system setting "pdotools_class_path".'; -$_lang['setting_pdotools_class_path'] = 'Base path to pdoTools class'; -$_lang['setting_pdotools_class_path_desc'] = 'Base path to pdoTools class from which it will be loaded with FQN.'; - -$_lang['setting_pdoFetch.class'] = 'FQN of pdoFetch'; -$_lang['setting_pdoFetch.class_desc'] = 'Path for loading class from system setting "pdofetch_class_path".'; -$_lang['setting_pdofetch_class_path'] = 'Base path to pdoFetch class'; -$_lang['setting_pdofetch_class_path_desc'] = 'Base path to pdoFetch class from which it will be loaded with FQN.'; - -$_lang['setting_pdoParser.class'] = 'FQN of pdoParser'; -$_lang['setting_pdoParser.class_desc'] = 'Path for loading class from system setting "parser_class_path".'; -$_lang['setting_parser_class'] = 'Parser class'; -$_lang['setting_parser_class_desc'] = 'Parser class that will be used to process the MODX tags.'; -$_lang['setting_parser_class_path'] = 'The path to the parser'; -$_lang['setting_parser_class_path_desc'] = 'Base path to parser class from which it will be loaded with FQN.'; - $_lang['setting_pdotools_elements_path'] = 'Path to elements'; $_lang['setting_pdotools_elements_path_desc'] = 'Directory with file elements to load via @FILE binding.'; $_lang['setting_pdotools_fenom_default'] = 'Use Fenom for chunks'; @@ -42,4 +25,7 @@ $_lang['setting_pdotools_fenom_cache'] = 'Caching compiled chunks'; $_lang['setting_pdotools_fenom_cache_desc'] = 'If you use large and complex Fenom chunks, you can enable caching of its compiled versions. They will be updated only when you clear the system cache. Not recommended for the development of the site.'; $_lang['setting_pdotools_fenom_save_on_errors'] = 'Save errors'; -$_lang['setting_pdotools_fenom_save_on_errors_desc'] = 'Enable this option to save Fenom compilation errors to the "core/cache/default/pdotools/error" directory for later debugging.'; \ No newline at end of file +$_lang['setting_pdotools_fenom_save_on_errors_desc'] = 'Enable this option to save Fenom compilation errors to the "core/cache/default/pdotools/error" directory for later debugging.'; + +$_lang['setting_pdotools_filter_path'] = 'Filter the file element\'s path.'; +$_lang['setting_pdotools_filter_path_desc'] = 'Removes the "../" construction from the path to the file element.'; \ No newline at end of file diff --git a/core/components/pdotools/lexicon/ru/default.inc.php b/core/components/pdotools/lexicon/ru/default.inc.php index 358d766c..32a623ce 100644 --- a/core/components/pdotools/lexicon/ru/default.inc.php +++ b/core/components/pdotools/lexicon/ru/default.inc.php @@ -10,23 +10,6 @@ $_lang['area_pdotools_main'] = 'Основные'; -$_lang['setting_pdoTools.class'] = 'FQN имя класса pdoTools'; -$_lang['setting_pdoTools.class_desc'] = 'FQN имя класса pdoTools для загрузки из настройки "pdotools_class_path".'; -$_lang['setting_pdotools_class_path'] = 'Путь к классу pdoTools'; -$_lang['setting_pdotools_class_path_desc'] = 'Директории с классом pdoTools, из которого он будет загружен, используя FQN имя.'; - -$_lang['setting_pdoFetch.class'] = 'FQN имя класса pdoFetch'; -$_lang['setting_pdoFetch.class_desc'] = 'FQN имя класса pdoTools для загрузки из настройки "pdofetch_class_path".'; -$_lang['setting_pdofetch_class_path'] = 'Путь к классу pdoFetch'; -$_lang['setting_pdofetch_class_path_desc'] = 'Директории с классом pdoFetch, из которого он будет загружен, используя FQN имя.'; - -$_lang['setting_pdoParser.class'] = 'FQN имя класса pdoParser'; -$_lang['setting_pdoParser.class_desc'] = 'FQN имя класса pdoParser для загрузки из настройки "parser_class_path".'; -$_lang['setting_parser_class'] = 'Используемый парсер'; -$_lang['setting_parser_class_desc'] = 'Класс парсера, который используется для разбора тегов MODX.'; -$_lang['setting_parser_class_path'] = 'Путь к классу парсера'; -$_lang['setting_parser_class_path_desc'] = 'Директории с классом парсера, из которого он будет загружен, используя FQN имя.'; - $_lang['setting_pdotools_elements_path'] = 'Путь к элементам'; $_lang['setting_pdotools_elements_path_desc'] = 'Директория, в которой хранятся файлы элементов для загрузки через @FILE.'; $_lang['setting_pdotools_fenom_default'] = 'Использовать Fenom в чанках'; @@ -42,4 +25,6 @@ $_lang['setting_pdotools_fenom_cache'] = 'Кэширование скомпилированных чанков'; $_lang['setting_pdotools_fenom_cache_desc'] = 'Если вы используете большие и сложные чанки Fenom, то можно включить кэширование их скомпилированных версий. Они будут обновляться только при очистке системного кэша. Не рекомендуется при разработке сайта.'; $_lang['setting_pdotools_fenom_save_on_errors'] = 'Сохранять ошибки'; -$_lang['setting_pdotools_fenom_save_on_errors_desc'] = 'Включите эту опцию, чтобы сохранять ошибки компиляции Fenom в директорию "core/cache/default/pdotools/error" для последующей отладки.'; \ No newline at end of file +$_lang['setting_pdotools_fenom_save_on_errors_desc'] = 'Включите эту опцию, чтобы сохранять ошибки компиляции Fenom в директорию "core/cache/default/pdotools/error" для последующей отладки.'; +$_lang['setting_pdotools_filter_path'] = 'Фильтровать путь к файлу'; +$_lang['setting_pdotools_filter_path_desc'] = 'Удаляет из пути к файловому элементу конструкцию "../".'; \ No newline at end of file diff --git a/core/components/pdotools/model/fenom/Providers/ModFile.php b/core/components/pdotools/model/fenom/Providers/ModFile.php deleted file mode 100644 index 519f8af8..00000000 --- a/core/components/pdotools/model/fenom/Providers/ModFile.php +++ /dev/null @@ -1,21 +0,0 @@ -config['elementsPath']) - ? MODX_CORE_PATH . 'cache/' - : $pdoTools->config['elementsPath']; - parent::__construct($dir); - $this->pdoTools = $pdoTools; - $this->modx = $pdoTools->modx; - } - -} \ No newline at end of file diff --git a/core/components/pdotools/model/pdotools/metadata.mysql.php b/core/components/pdotools/model/pdotools/metadata.mysql.php deleted file mode 100644 index db8f07c7..00000000 --- a/core/components/pdotools/model/pdotools/metadata.mysql.php +++ /dev/null @@ -1,3 +0,0 @@ - array(), - 'snippet' => array(), - 'tv' => array(), - 'data' => array(), - 'resource' => array(), - ); - /** @var integer $idx Index of iterator of rows processing */ + protected $store = [ + 'chunk' => [], + 'snippet' => [], + 'tv' => [], + 'data' => [], + 'resource' => [], + ]; + /** @var int $idx Index of iterator of rows processing */ public $idx = 1; - /** @var integer $time Time of script start */ + /** @var array $timings Array with query log */ + protected $timings = []; + /** @var int $time Time of script start */ protected $time; - /** @var integer $count Total number of results for chunks processing */ + /** @var int $count Total number of results for chunks processing */ protected $count = 0; - /** @var boolean $preparing Specifies that now is the preparation */ + /** @var bool $preparing Specifies that now is the preparation */ protected $preparing = false; + /** @var int */ protected $start = 0; - /** @var pdoParser $parser */ - public $parser; - /** @var Fenom $fenom */ - public $fenom; - private $tags = array(); - public $ignores = array(); + + private $tags = []; /** * @param modX $modx * @param array $config */ - public function __construct(modX & $modx, $config = array()) + public function __construct(modX $modx, array $config = []) { - $this->modx = $modx; $this->time = $this->start = microtime(true); + $this->modx = $modx; $this->setConfig($config); } @@ -52,11 +65,10 @@ public function __construct(modX & $modx, $config = array()) * @param array $config * @param bool $clean_timings Clean timings array */ - public function setConfig(array $config = array(), $clean_timings = true) + public function setConfig(array $config = [], bool $clean_timings = true) { - $this->config = array_merge(array( + $this->config = array_merge([ 'fastMode' => false, - 'nestedChunkPrefix' => 'pdotools_', 'offset' => 0, 'checkPermissions' => '', @@ -69,12 +81,12 @@ public function setConfig(array $config = array(), $clean_timings = true) 'decodeJSON' => true, 'scheme' => '', 'fenomSyntax' => $this->modx->getOption('pdotools_fenom_syntax', null, '#\{(\$|\/|\w+(\s|\(|\|)|\(|\')#', true), - 'elementsPath' => $this->modx->getOption('pdotools_elements_path', null, '{core_path}elements/', true), - 'cachePath' => '{core_path}cache/default/pdotools', - ), $config); + ], $config); + $this->config['elementsPath'] = $this->modx->getOption('pdotools_elements_path', null, MODX_CORE_PATH . 'elements/', true); + $this->config['cachePath'] = MODX_CORE_PATH . 'cache/pdotools'; if ($clean_timings) { - $this->timings = array(); + $this->timings = []; } if (empty($this->config['scheme'])) { @@ -88,68 +100,55 @@ public function setConfig(array $config = array(), $clean_timings = true) $this->config['useFenomCache'] = $this->modx->getOption('pdotools_fenom_cache', null, false); $this->config['useFenomMODX'] = $this->modx->getOption('pdotools_fenom_modx', null, false); $this->config['useFenomPHP'] = $this->modx->getOption('pdotools_fenom_php', null, false); + $this->config['filterPath'] = $this->modx->getOption('pdotools_filter_path', null, true); // Chunk file extensions $this->config['chunkExtensions'] = explode(',', str_replace(' ', '', $this->modx->getOption('pdotools_file_chunk_extensions', null, 'html,tpl'))); // Prepare paths - $pl = array( + $pl = [ 'core_path' => MODX_CORE_PATH, 'assets_path' => MODX_ASSETS_PATH, 'base_path' => MODX_BASE_PATH, - ); + ]; $pl1 = $this->makePlaceholders($pl, '', '{', '}', false); $pl2 = $this->makePlaceholders($pl, '', '[[+', ']]', false); - foreach (array('elementsPath', 'cachePath') as $k) { + foreach (['elementsPath', 'cachePath'] as $k) { $this->config[$k] = str_replace($pl1['pl'], $pl1['vl'], str_replace($pl2['pl'], $pl2['vl'], $this->config[$k]) ); } } - /** - * Loads pdoTools parser - * - * @return pdoParser + * @param string|array|null $key Key to get or array to set. + * @param mixed $default + * @return mixed */ - protected function getParser() + public function config($key = null, $default = null) { - $this->parser = $this->modx->getParser(); - if (!($this->parser instanceof pdoParser)) { - if (!class_exists('pdoParser')) { - require_once dirname(__FILE__) . '/pdoparser.class.php'; - } - $this->parser = new pdoParser($this->modx); + if (null === $key) { + return $this->config; } - - return $this->parser; + if (is_array($key)) { + $this->config = array_merge($this->config, $key); + return $this; + } + return $this->config[$key] ?? $default; } - /** - * Loads template engine - * - * @return bool|Fenom + * @return Fenom */ public function getFenom() { - if (!$this->fenom) { - try { - if (!class_exists('FenomX')) { - require '_fenom.php'; - } - $this->fenom = new FenomX($this); - } catch (Exception $e) { - $this->modx->log(xPDO::LOG_LEVEL_ERROR, $e->getMessage()); - - return false; - } + if (!$this->modx->services->has('fenom')) { + $class = $this->modx->getOption('pdotools_fenom_class', null, Fenom::class, true); + $this->modx->services->add('fenom', new $class($this->modx, $this)); } - return $this->fenom; + return $this->modx->services->get('fenom'); } - /** * Add new record to time log * @@ -163,10 +162,10 @@ public function addTime($message, $delta = null) $delta = $time - $this->time; } - $this->timings[] = array( + $this->timings[] = [ 'time' => number_format(round(($delta), 7), 7), 'message' => $message, - ); + ]; $this->time = $time; } @@ -180,33 +179,33 @@ public function addTime($message, $delta = null) */ public function getTime($string = true) { - $this->timings[] = array( + $this->timings[] = [ 'time' => number_format(round(microtime(true) - $this->start, 7), 7), 'message' => 'Total time', - ); - $this->timings[] = array( + ]; + $this->timings[] = [ 'time' => number_format(round((memory_get_usage(true)), 2), 0, ',', ' '), 'message' => 'Memory usage', - ); + ]; if (!$string) { return $this->timings; - } else { - $res = ''; - foreach ($this->timings as $v) { - $res .= $v['time'] . ': ' . $v['message'] . "\n"; - } + } - return $res; + $res = ''; + foreach ($this->timings as $v) { + $res .= $v['time'] . ': ' . $v['message'] . "\n"; } + + return $res; } /** * Set data to cache * - * @param $name - * @param $object + * @param string $name + * @param mixed $object * @param string $type */ public function setStore($name, $object, $type = 'data') @@ -218,16 +217,14 @@ public function setStore($name, $object, $type = 'data') /** * Get data from cache * - * @param $name + * @param string $name * @param string $type * * @return mixed|null */ public function getStore($name, $type = 'data') { - return isset($this->store[$type][$name]) - ? $this->store[$type][$name] - : null; + return $this->store[$type][$name] ?? null; } @@ -241,19 +238,19 @@ public function loadModels() } $time = microtime(true); - $models = array(); + $models = []; if (strpos(ltrim($this->config['loadModels']), '{') === 0) { $tmp = json_decode($this->config['loadModels'], true); foreach ($tmp as $k => $v) { if (!is_array($v)) { - $v = array( + $v = [ 'path' => trim($v), - ); + ]; } - $v = array_merge(array( + $v = array_merge([ 'path' => MODX_CORE_PATH . 'components/' . strtolower($k) . '/model/', 'prefix' => null, - ), $v); + ], $v); if (strpos($v['path'], MODX_CORE_PATH) === false) { $v['path'] = MODX_CORE_PATH . ltrim($v['path'], '/'); } @@ -263,16 +260,16 @@ public function loadModels() $tmp = array_map('trim', explode(',', $this->config['loadModels'])); foreach ($tmp as $v) { $parts = explode(':', $v, 2); - $models[$parts[0]] = array( + $models[$parts[0]] = [ 'path' => MODX_CORE_PATH . 'components/' . strtolower($parts[0]) . '/model/', 'prefix' => count($parts) > 1 ? $parts[1] : null, - ); + ]; } } if (!empty($models)) { foreach ($models as $k => $v) { - $t = '/' . str_replace(array(MODX_BASE_PATH, MODX_CORE_PATH), '', $v['path']); + $t = '/' . str_replace([MODX_BASE_PATH, MODX_CORE_PATH], '', $v['path']); if ($this->modx->addPackage(strtolower($k), $v['path'], $v['prefix'])) { $this->addTime('Loaded model "' . $k . '" from "' . $t . '"', microtime(true) - $time); } else { @@ -298,13 +295,13 @@ public function loadModels() * @return array */ public function makePlaceholders( - array $array = array(), + array $array = [], $plPrefix = '', $prefix = '[[+', $suffix = ']]', $uncacheable = true ) { - $result = array('pl' => array(), 'vl' => array()); + $result = ['pl' => [], 'vl' => []]; $uncached_prefix = str_replace('[[', '[[!', $prefix); foreach ($array as $k => $v) { @@ -334,7 +331,7 @@ public function makePlaceholders( * * @return mixed The processed output of the Snippet. */ - public function runSnippet($name, array $properties = array()) + public function runSnippet($name, array $properties = []) { $name = trim($name); /** @var array $data */ @@ -342,20 +339,19 @@ public function runSnippet($name, array $properties = array()) $data = $this->_loadElement($name, 'modSnippet', $properties); } if (empty($data) || !($data['object'] instanceof modSnippet)) { - $this->modx->log(modX::LOG_LEVEL_ERROR, "[pdoTools] Could not load snippet \"{$name}\""); + $this->modx->log(MODX_LOG_LEVEL_ERROR, "[pdoTools] Could not load snippet \"{$name}\""); return false; } - /** @var modSnippet $snippet */ $snippet = $data['object']; $snippet->_cacheable = $data['cacheable']; $snippet->_processed = false; $snippet->_propertyString = ''; $snippet->_tag = ''; if ($data['cacheable'] && !$this->modx->getParser()->isProcessingUncacheable()) { - $scripts = array('jscripts', 'sjscripts', 'loadedjscripts'); - $regScriptsBefore = $regScriptsAfter = array(); + $scripts = ['jscripts', 'sjscripts', 'loadedjscripts']; + $regScriptsBefore = $regScriptsAfter = []; foreach ($scripts as $prop) { $regScriptsBefore[$prop] = count($this->modx->$prop); } @@ -370,7 +366,7 @@ public function runSnippet($name, array $properties = array()) $resProp = '_' . $prop; foreach (array_slice($this->modx->{$prop}, $regScriptsBefore[$prop]) as $key => $value) { if (!is_array($this->modx->resource->{$resProp})) { - $this->modx->resource->{$resProp} = array(); + $this->modx->resource->{$resProp} = []; } if ($prop == 'loadedjscripts') { @@ -395,12 +391,13 @@ public function runSnippet($name, array $properties = array()) * Process and return the output from a Chunk by name. * * @param string $name 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. - * @param boolean $fastMode If false, all MODX tags in chunk will be processed. + * @param array $properties An associative array of properties to process the Chunk with, + * treated as placeholders within the scope of the Element. + * @param bool $fastMode If false, all MODX tags in chunk will be processed. * * @return mixed The processed output of the Chunk. */ - public function getChunk($name = '', array $properties = array(), $fastMode = false) + public function getChunk($name = '', array $properties = [], $fastMode = false) { $properties = $this->prepareRow($properties); $name = trim($name); @@ -411,42 +408,20 @@ public function getChunk($name = '', array $properties = array(), $fastMode = fa } if (empty($name) || empty($data) || !($data['object'] instanceof modElement)) { return !empty($properties) - ? str_replace(array('[', ']', '`'), array('[', ']', '`'), + ? str_replace(['[', ']', '`'], ['[', ']', '`'], htmlentities(print_r($properties, true), ENT_QUOTES, 'UTF-8')) : ''; } $properties = array_merge($data['properties'], $properties); $content = $this->config['useFenom'] - ? $this->fenom($data, $properties) + ? $this->getFenom()->process($data, $properties) : $data['content']; - if (strpos($content, '[[') !== false) { - // Processing quick placeholders - if (!empty($data['placeholders'])) { - $properties = $this->flattenArray($properties); - $pl = $data['placeholders']; - foreach ($pl as $k => $v) { - if ($k[0] == '!') { - if (empty($properties[substr($k, 1)])) { - $pl[substr($k, 1)] = $v; - } - unset($pl[$k]); - } elseif (empty($properties[$k])) { - $pl[$k] = ''; - } - } - if (!empty($pl)) { - $pl = $this->makePlaceholders($pl); - $content = str_replace($pl['pl'], $pl['vl'], $content); - } - } - - // Processing given placeholders - if (!empty($properties)) { - $pl = $this->makePlaceholders($properties); - $content = str_replace($pl['pl'], $pl['vl'], $content); - } + // Processing given placeholders + if ((strpos($content, '[[') !== false) && !empty($properties)) { + $pl = $this->makePlaceholders($properties); + $content = str_replace($pl['pl'], $pl['vl'], $content); } // Processing other placeholders @@ -478,7 +453,7 @@ public function getChunk($name = '', array $properties = array(), $fastMode = fa * * @return string The processed chunk with the placeholders replaced. */ - public function parseChunk($name = '', array $properties = array(), $prefix = '[[+', $suffix = ']]') + public function parseChunk($name = '', array $properties = [], $prefix = '[[+', $suffix = ']]') { $properties = $this->prepareRow($properties); $name = trim($name); @@ -489,14 +464,14 @@ public function parseChunk($name = '', array $properties = array(), $prefix = '[ } if (empty($name) || empty($chunk['content'])) { return !empty($properties) - ? str_replace(array('[', ']', '`'), array('[', ']', '`'), + ? str_replace(['[', ']', '`'], ['[', ']', '`'], htmlentities(print_r($properties, true), ENT_QUOTES, 'UTF-8')) : ''; } $properties = array_merge($chunk['properties'], $properties); $content = $this->config['useFenom'] - ? $this->fenom($chunk, $properties) + ? $this->getFenom()->process($chunk, $properties) : $chunk['content']; if (strpos($content, '[[') !== false) { @@ -508,89 +483,6 @@ public function parseChunk($name = '', array $properties = array(), $prefix = '[ } - /** - * @param string|array $chunk - * @param array $properties - * - * @return mixed|string - */ - public function fenom($chunk, array $properties = array()) - { - $content = is_array($chunk) - ? trim($chunk['content']) - : trim($chunk); - if (empty($this->config['useFenom']) || !preg_match($this->config['fenomSyntax'], $content)) { - return $content; - } - - if ($fenom = $this->getFenom()) { - $name = ''; - if (is_array($chunk)) { - if (!empty($chunk['binding'])) { - $name = $chunk['binding'] . '/'; - } - if (!empty($chunk['id'])) { - $name .= $chunk['id']; - } elseif (!empty($chunk['name'])) { - $name .= $chunk['name']; - } else { - $name .= md5($content); - } - } else { - $name = md5($content); - } - /** @var Fenom\Template $tpl */ - if (!$tpl = $this->getStore($name, 'fenom')) { - if (!empty($this->config['useFenomCache'])) { - $cache_options = array( - 'cache_key' => 'pdotools/' . $name, - ); - if (!$cache = $this->getCache($cache_options)) { - if ($tpl = $this->_compileChunk($content, $name)) { - $this->setCache($tpl->getTemplateCode(), $cache_options); - } - } else { - $cache = preg_replace('#^<\?php#', '', $cache); - $tpl = eval($cache); - } - } else { - $tpl = $this->_compileChunk($content, $name); - } - if ($tpl) { - $this->setStore($name, $tpl, 'fenom'); - } - } - - if ($tpl instanceof Fenom\Render) { - // Add system variables - if (!$microMODX = $this->getStore('microMODX')) { - if (!class_exists('microMODX')) { - require '_micromodx.php'; - } - $microMODX = new microMODX($this); - $this->setStore('microMODX', $microMODX); - } - $properties['_modx'] = $microMODX; - $properties['_pls'] = $properties; - - // Add system objects - if (!empty($this->config['useFenomMODX'])) { - $properties['modx'] = $this->modx; - $properties['pdoTools'] = $this; - } - try { - $content = $tpl->fetch($properties); - } catch (Exception $e) { - $this->modx->log(modX::LOG_LEVEL_ERROR, $e->getMessage()); - $this->modx->log(modX::LOG_LEVEL_INFO, $tpl->getTemplateCode()); - } - } - } - - return $content; - } - - /** * Fast processing of MODX tags. * @@ -601,12 +493,12 @@ public function fenom($chunk, array $properties = array()) */ public function fastProcess($content, $processUncacheable = true) { - $matches = array(); - $this->getParser()->collectElementTags($content, $matches); + $matches = []; + $this->modx->getParser()->collectElementTags($content, $matches); - $unprocessed = $pl = $vl = array(); + $unprocessed = $pl = $vl = []; foreach ($matches as $tag) { - $tmp = $this->parser->processTag($tag, $processUncacheable); + $tmp = $this->modx->getParser()->processTag($tag, $processUncacheable); if ($tmp === $tag[0]) { $unprocessed[] = $tmp; @@ -631,42 +523,36 @@ public function fastProcess($content, $processUncacheable = true) * * @return mixed */ - public function defineChunk($properties = array()) + public function defineChunk(array $properties = []) { - $idx = isset($properties['idx']) ? (integer)$properties['idx'] : $this->idx++; + $idx = isset($properties['idx']) ? (int)$properties['idx'] : $this->idx++; $idx -= $this->config['offset']; - $first = empty($this->config['first']) ? ($this->config['offset'] + 1) : (integer)$this->config['first']; + $first = empty($this->config['first']) ? ($this->config['offset'] + 1) : (int)$this->config['first']; $last = empty($this->config['last']) ? ($this->count + $this->config['offset']) - : (integer)$this->config['last']; + : (int)$this->config['last']; $odd = !($idx & 1); $resourceTpl = ''; - if ($idx == $first && !empty($this->config['tplFirst'])) { + if ($idx === $first && !empty($this->config['tplFirst'])) { $resourceTpl = $this->config['tplFirst']; - } else { - if ($idx == $last && !empty($this->config['tplLast'])) { - $resourceTpl = $this->config['tplLast']; - } else { - if (!empty($this->config['tpl_' . $idx])) { - $resourceTpl = $this->config['tpl_' . $idx]; - } else { - if ($idx > 1) { - $divisors = array(); - for ($i = $idx; $i > 1; $i--) { - if (($idx % $i) === 0) { - $divisors[] = $i; - } - } - if (!empty($divisors)) { - foreach ($divisors as $divisor) { - if (!empty($this->config['tpl_n' . $divisor])) { - $resourceTpl = $this->config['tpl_n' . $divisor]; - break; - } - } - } + } elseif ($idx === $last && !empty($this->config['tplLast'])) { + $resourceTpl = $this->config['tplLast']; + } elseif (!empty($this->config['tpl_' . $idx])) { + $resourceTpl = $this->config['tpl_' . $idx]; + } elseif ($idx > 1) { + $divisors = []; + for ($i = $idx; $i > 1; $i--) { + if (($idx % $i) === 0) { + $divisors[] = $i; + } + } + if (!empty($divisors)) { + foreach ($divisors as $divisor) { + if (!empty($this->config['tpl_n' . $divisor])) { + $resourceTpl = $this->config['tpl_n' . $divisor]; + break; } } } @@ -674,100 +560,98 @@ public function defineChunk($properties = array()) if (empty($resourceTpl) && $odd && !empty($this->config['tplOdd'])) { $resourceTpl = $this->config['tplOdd']; - } else { - if (empty($resourceTpl) && !empty($this->config['tplCondition']) && !empty($this->config['conditionalTpls'])) { - $conTpls = json_decode($this->config['conditionalTpls'], true); - if (isset($properties[$this->config['tplCondition']])) { - $subject = $properties[$this->config['tplCondition']]; - $tplOperator = !empty($this->config['tplOperator']) - ? strtolower($this->config['tplOperator']) - : '='; - $tplCon = ''; - foreach ($conTpls as $operand => $conditionalTpl) { - switch ($tplOperator) { - case '!=': - case 'neq': - case 'not': - case 'isnot': - case 'isnt': - case 'unequal': - case 'notequal': - $tplCon = (($subject != $operand) ? $conditionalTpl : $tplCon); - break; - case '<': - case 'lt': - case 'less': - case 'lessthan': - $tplCon = (($subject < $operand) ? $conditionalTpl : $tplCon); - break; - case '>': - case 'gt': - case 'greater': - case 'greaterthan': - $tplCon = (($subject > $operand) ? $conditionalTpl : $tplCon); - break; - case '<=': - case 'lte': - case 'lessthanequals': - case 'lessthanorequalto': - $tplCon = (($subject <= $operand) ? $conditionalTpl : $tplCon); - break; - case '>=': - case 'gte': - case 'greaterthanequals': - case 'greaterthanequalto': - $tplCon = (($subject >= $operand) ? $conditionalTpl : $tplCon); - break; - case 'isempty': - case 'empty': - $tplCon = empty($subject) ? $conditionalTpl : $tplCon; - break; - case '!empty': - case 'notempty': - case 'isnotempty': - $tplCon = !empty($subject) && $subject != '' ? $conditionalTpl : $tplCon; - break; - case 'isnull': - case 'null': - $tplCon = $subject == null || strtolower($subject) == 'null' - ? $conditionalTpl - : $tplCon; - break; - case 'inarray': - case 'in_array': - case 'ia': - $operand = explode(',', $operand); - $tplCon = in_array($subject, $operand) ? $conditionalTpl : $tplCon; - break; - case 'between': - case 'range': - case '>=<': - case '><': - $operand = explode(',', $operand); - $tplCon = ($subject >= min($operand) && $subject <= max($operand)) - ? $conditionalTpl - : $tplCon; - break; - case 'contains': - $tplCon = is_string($subject) && - (strpos($subject, $operand) !== false ? $conditionalTpl : $tplCon); - break; - case '==': - case '=': - case 'eq': - case 'is': - case 'equal': - case 'equals': - case 'equalto': - default: - $tplCon = (($subject == $operand) ? $conditionalTpl : $tplCon); - break; - } + } elseif (empty($resourceTpl) && !empty($this->config['tplCondition']) && !empty($this->config['conditionalTpls'])) { + $conTpls = json_decode($this->config['conditionalTpls'], true); + if (isset($properties[$this->config['tplCondition']])) { + $subject = $properties[$this->config['tplCondition']]; + $tplOperator = !empty($this->config['tplOperator']) + ? strtolower($this->config['tplOperator']) + : '='; + $tplCon = ''; + foreach ($conTpls as $operand => $conditionalTpl) { + switch ($tplOperator) { + case '!=': + case 'neq': + case 'not': + case 'isnot': + case 'isnt': + case 'unequal': + case 'notequal': + $tplCon = (($subject != $operand) ? $conditionalTpl : $tplCon); + break; + case '<': + case 'lt': + case 'less': + case 'lessthan': + $tplCon = (($subject < $operand) ? $conditionalTpl : $tplCon); + break; + case '>': + case 'gt': + case 'greater': + case 'greaterthan': + $tplCon = (($subject > $operand) ? $conditionalTpl : $tplCon); + break; + case '<=': + case 'lte': + case 'lessthanequals': + case 'lessthanorequalto': + $tplCon = (($subject <= $operand) ? $conditionalTpl : $tplCon); + break; + case '>=': + case 'gte': + case 'greaterthanequals': + case 'greaterthanequalto': + $tplCon = (($subject >= $operand) ? $conditionalTpl : $tplCon); + break; + case 'isempty': + case 'empty': + $tplCon = empty($subject) ? $conditionalTpl : $tplCon; + break; + case '!empty': + case 'notempty': + case 'isnotempty': + $tplCon = !empty($subject) && $subject != '' ? $conditionalTpl : $tplCon; + break; + case 'isnull': + case 'null': + $tplCon = $subject == null || strtolower($subject) == 'null' + ? $conditionalTpl + : $tplCon; + break; + case 'inarray': + case 'in_array': + case 'ia': + $operand = explode(',', $operand); + $tplCon = in_array($subject, $operand) ? $conditionalTpl : $tplCon; + break; + case 'between': + case 'range': + case '>=<': + case '><': + $operand = explode(',', $operand); + $tplCon = ($subject >= min($operand) && $subject <= max($operand)) + ? $conditionalTpl + : $tplCon; + break; + case 'contains': + $tplCon = is_string($subject) && + (strpos($subject, $operand) !== false ? $conditionalTpl : $tplCon); + break; + case '==': + case '=': + case 'eq': + case 'is': + case 'equal': + case 'equals': + case 'equalto': + default: + $tplCon = (($subject == $operand) ? $conditionalTpl : $tplCon); + break; } } - if (!empty($tplCon)) { - $resourceTpl = $tplCon; - } + } + if (!empty($tplCon)) { + $resourceTpl = $tplCon; } } @@ -788,40 +672,40 @@ public function defineChunk($properties = array()) * * @return array|bool */ - protected function _loadElement($name, $type, $row = array()) + protected function _loadElement($name, $type, $row = []) { $binding = $content = $propertySet = ''; $name = trim($name); - if (preg_match('#^@([A-Z]+)#', $name, $matches)) { + if (preg_match('#^!?@([A-Z]+)#', $name, $matches)) { $binding = $matches[1]; - $content = substr($name, strlen($binding) + 1); + $content = preg_replace('#^!?@' . $binding . '#', '', $name); $content = ltrim($content, ' :'); } // Get property set if (!$binding && $pos = strpos($name, '@')) { $propertySet = substr($name, $pos + 1); $name = substr($name, 0, $pos); - } elseif (in_array($binding, array('CHUNK', 'TEMPLATE', 'SNIPPET')) && $pos = strpos($content, '@')) { + } elseif (in_array($binding, ['CHUNK', 'TEMPLATE', 'SNIPPET']) && $pos = strpos($content, '@')) { $propertySet = substr($content, $pos + 1); $content = substr($content, 0, $pos); } - if ($type == 'modChunk' || $type == 'modTemplate') { + if ($type === 'modChunk' || $type === 'modTemplate') { // Replace inline tags in chunks - $content = str_replace(array('{{', '}}'), array('[[', ']]'), $content); + $content = str_replace(['{{', '}}'], ['[[', ']]'], $content); // Change name for empty TEMPLATE binding so will be used template of given row - if ($binding == 'TEMPLATE' && empty($content) && isset($row['template'])) { + if ($binding === 'TEMPLATE' && empty($content) && isset($row['template'])) { $name = '@TEMPLATE ' . $row['template']; $content = $row['template']; } } - $cache_name = !empty($binding) && !in_array($binding, array('CHUNK', 'SNIPPET')) + $cache_name = !empty($binding) && !in_array($binding, ['CHUNK', 'SNIPPET']) ? md5($name) : $name; - if (strpos($cache_name, '!') === 0) { + if ($cache_name[0] === '!') { $cache_name = substr($cache_name, 1); $cacheable = false; } else { @@ -837,12 +721,12 @@ protected function _loadElement($name, $type, $row = array()) return $element; } - $properties = array(); + $properties = []; /** @var modElement $element */ switch ($binding) { case 'CODE': case 'INLINE': - $element = $this->modx->newObject($type, array('name' => $cache_name)); + $element = $this->modx->newObject($type, ['name' => $cache_name]); if ($element instanceof modScript) { if (empty($this->config['useFenomPHP']) || empty($this->config['useFenomMODX'])) { $this->addTime('Could not create inline "' . $type . '" because of system settings.'); @@ -857,22 +741,17 @@ protected function _loadElement($name, $type, $row = array()) $cacheable = false; break; case 'FILE': - if (!empty($row['tplPath']) || !empty($row['elementsPath'])) { - // @Deprecated - $this->modx->log(modX::LOG_LEVEL_ERROR, '[pdoTools] The "tplPath" and "elementsPath" parameters are deprecated and will be removed in the next version.'); - $path = !empty($row['tplPath']) ? $row['tplPath'] : $row['elementsPath']; - } else { - $path = $this->config['elementsPath']; - } - - if (strpos($path, MODX_BASE_PATH) === false && strpos($path, MODX_CORE_PATH) === false) { + // TODO: Сделать несколько путей. + $path = $this->config['elementsPath']; + $filename = $content; + if (strpos($path, MODX_BASE_PATH) === false && strpos($path, './') === 0) { $path = MODX_BASE_PATH . $path; } - $path = preg_replace(["/\.*[\/|\\\]/i", "/[\/|\\\]+/i"], ['/', '/'], $path . $content); - $rel_path = str_replace(array(MODX_BASE_PATH, MODX_CORE_PATH), '', $path); + $path = $this->config['filterPath'] ? preg_replace(["/\.*[\/|\\\]/i", "/[\/|\\\]+/i"], ['/', '/'], $path . $filename) : $path . $filename; + //$rel_path = str_replace([MODX_BASE_PATH, MODX_CORE_PATH], '', $path); if (!file_exists($path)) { - $message = 'Could not find the element file "' . $rel_path . '".'; - $this->modx->log(modX::LOG_LEVEL_ERROR, $message); + $message = 'Could not find the element file "' . $content . '".'; + $this->modx->log(MODX_LOG_LEVEL_ERROR, $message); $this->addTime($message); return false; @@ -880,13 +759,13 @@ protected function _loadElement($name, $type, $row = array()) $fileExtension = pathinfo($path, PATHINFO_EXTENSION); if (!$this->isAllowedFileExtension($fileExtension, $type)) { $message = 'File extension "' . $fileExtension . '" is not allowed for element type ' . $type . '!'; - $this->modx->log(modX::LOG_LEVEL_ERROR, $message); + $this->modx->log(MODX_LOG_LEVEL_ERROR, $message); $this->addTime($message); return false; } if ($content = file_get_contents($path)) { - $element = $this->modx->newObject($type, array('name' => $cache_name)); + $element = $this->modx->newObject($type, ['name' => $cache_name]); $element->setContent($content); $element->setProperties($properties); if ($element instanceof modScript) { @@ -895,32 +774,32 @@ protected function _loadElement($name, $type, $row = array()) } //$element->set('static', true); //$element->set('static_file', $path); - $this->addTime('Created "' . $type . '" from file "' . $rel_path . '"'); + $this->addTime('Created "' . $type . '" from file "' . $filename . '"'); } $cacheable = false; break; case 'TEMPLATE': - if ($type != 'modSnippet') { + if ($type !== 'modSnippet') { return $this->_loadElement($content, 'modTemplate', $row); } break; case 'CHUNK': - if ($type == 'modChunk') { + if ($type === 'modChunk') { return $this->_loadElement($content, 'modChunk', $row); } break; case 'SNIPPET': - if ($type == 'modSnippet') { + if ($type === 'modSnippet') { return $this->_loadElement($content, 'modSnippet', $row); } break; default: - $column = $type == 'modTemplate' + $column = $type === 'modTemplate' ? 'templatename' : 'name'; $c = filter_var($cache_name, FILTER_VALIDATE_INT) === false - ? array($column . ':=' => $cache_name) - : array('id:=' => $cache_name, 'OR:' . $column . ':=' => $cache_name); + ? [$column . ':=' => $cache_name] + : ['id:=' => $cache_name, 'OR:' . $column . ':=' => $cache_name]; if ($element = $this->modx->getObject($type, $c)) { $content = $element->getContent(); if (!empty($propertySet)) { @@ -940,76 +819,20 @@ protected function _loadElement($name, $type, $row = array()) return false; } - $placeholders = array(); - if (!($element instanceof modScript)) { - // Preparing special tags - if (strpos($content, '#s', - $content, - $matches - ); - $src = $dst = $placeholders = array(); - foreach ($matches[1] as $k => $v) { - $src[] = $matches[0][$k]; - $dst[] = ''; - $placeholders[$v] = $matches[2][$k]; - } - if (!empty($src) && !empty($dst)) { - $content = str_replace($src, $dst, $content); - } - } - } - - $data = array( + $data = [ 'object' => $element, 'content' => $content, - 'placeholders' => $placeholders, 'properties' => $properties, 'name' => $cache_name, 'id' => (int)$element->get('id'), 'binding' => strtolower($type), 'cacheable' => $cacheable, - ); + ]; $this->setStore($cache_key, $data, $type); return $data; } - - /** - * Compiles Fenom chunk - * - * @param $content - * @param string $name - * - * @return bool|\Fenom\Template - */ - protected function _compileChunk($content, $name = '') - { - $tpl = false; - if ($fenom = $this->getFenom()) { - if (empty($name)) { - $name = md5($content); - } - try { - $tpl = $fenom->getRawTemplate()->source($name, $content, true); - $this->addTime('Compiled Fenom chunk with name "' . $name . '"'); - } catch (Exception $e) { - $this->modx->log(modX::LOG_LEVEL_ERROR, $e->getMessage()); - $this->modx->log(modX::LOG_LEVEL_INFO, $content); - if ($this->modx->getOption('pdotools_fenom_save_on_errors')) { - $this->setCache($content, array('cache_key' => 'pdotools/error/' . $name)); - } - $tpl = $fenom->getRawTemplate()->source($name, '', false); - $this->addTime('Can`t compile Fenom chunk with name "' . $name . '": ' . $e->getMessage()); - } - } - - return $tpl; - } - - /** * Builds a hierarchical tree from given array * @@ -1020,7 +843,7 @@ protected function _compileChunk($content, $name = '') * * @return array */ - public function buildTree($tmp = array(), $id = 'id', $parent = 'parent', array $roots = array()) + public function buildTree($tmp = [], $id = 'id', $parent = 'parent', array $roots = []) { $time = microtime(true); @@ -1031,26 +854,26 @@ public function buildTree($tmp = array(), $id = 'id', $parent = 'parent', array $parent = 'parent'; } - if (count($tmp) == 1) { + if (count($tmp) === 1) { $row = current($tmp); - $tree = array( - $row[$parent] => array( - 'children' => array( + $tree = [ + $row[$parent] => [ + 'children' => [ $row[$id] => $row, - ), - ), - ); + ], + ], + ]; } else { - $rows = $tree = array(); + $rows = $tree = []; foreach ($tmp as $v) { $rows[$v[$id]] = $v; } - foreach ($rows as $id => &$row) { - if (empty($row[$parent]) || (!isset($rows[$row[$parent]]) && in_array($id, $roots))) { - $tree[$id] = &$row; + foreach ($rows as $rid => &$row) { + if (empty($row[$parent]) || (!isset($rows[$row[$parent]]) && in_array($rid, $roots))) { + $tree[$rid] = &$row; } else { - $rows[$row[$parent]]['children'][$id] = &$row; + $rows[$row[$parent]]['children'][$rid] = &$row; } } } @@ -1068,10 +891,10 @@ public function buildTree($tmp = array(), $id = 'id', $parent = 'parent', array * * @return array */ - public function prepareRows(array $rows = array()) + public function prepareRows(array $rows = []) { $time = microtime(true); - $prepare = $process = $prepareTypes = array(); + $prepare = $process = $prepareTypes = []; if (!empty($this->config['includeTVs']) && (!empty($this->config['prepareTVs']) || !empty($this->config['processTVs']))) { $tvs = array_map('trim', explode(',', $this->config['includeTVs'])); $prepare = ($this->config['prepareTVs'] == 1) @@ -1092,9 +915,9 @@ public function prepareRows(array $rows = array()) // Extract JSON fields if ($this->config['decodeJSON']) { foreach ($row as $k => $v) { - if (!empty($v) && is_string($v) && ($v[0] == '[' || $v[0] == '{')) { + if (!empty($v) && is_string($v) && ($v[0] === '[' || $v[0] === '{')) { $tmp = json_decode($v, true); - if (json_last_error() == JSON_ERROR_NONE) { + if (json_last_error() === JSON_ERROR_NONE) { $row[$k] = $tmp; } } @@ -1110,7 +933,7 @@ public function prepareRows(array $rows = array()) /** @var modTemplateVar $templateVar */ if (!$templateVar = $this->getStore($tv, 'tv')) { - if ($templateVar = $this->modx->getObject('modTemplateVar', array('name' => $tv))) { + if ($templateVar = $this->modx->getObject('modTemplateVar', ['name' => $tv])) { $sourceCache = isset($prepareTypes[$templateVar->type]) ? $templateVar->getSourceCache($this->modx->context->get('key')) : null; @@ -1122,9 +945,7 @@ public function prepareRows(array $rows = array()) } } - $tvPrefix = !empty($this->config['tvPrefix']) ? - trim($this->config['tvPrefix']) - : ''; + $tvPrefix = !empty($this->config['tvPrefix']) ? trim($this->config['tvPrefix']) : ''; $key = $tvPrefix . $templateVar->name; if (isset($process[$tv])) { $row[$key] = $templateVar->renderOutput($row['id']); @@ -1132,7 +953,7 @@ public function prepareRows(array $rows = array()) '://') === false && method_exists($templateVar, 'prepareOutput') ) { if (isset($templateVar->sourceCache) && $source = $templateVar->sourceCache) { - if ($source['class_key'] == 'modFileMediaSource') { + if ($source['class_key'] === modFileMediaSource::class) { if (!empty($source['baseUrl']) && !empty($row[$key])) { $row[$key] = $source['baseUrl'] . $row[$key]; if (isset($source['baseUrlRelative']) && !empty($source['baseUrlRelative'])) { @@ -1165,7 +986,7 @@ public function prepareRows(array $rows = array()) * * @return array */ - public function prepareRow($row = array()) + public function prepareRow(array $row = []) { if ($this->preparing) { return $row; @@ -1177,17 +998,17 @@ public function prepareRow($row = array()) array_walk_recursive($row, function (&$value) { $value = str_replace( - array('[', ']', '{', '}'), - array('*(*(*(*(*(*', '*)*)*)*)*)*', '~(~(~(~(~(~', '~)~)~)~)~)~'), + ['[', ']', '{', '}'], + ['*(*(*(*(*(*', '*)*)*)*)*)*', '~(~(~(~(~(~', '~)~)~)~)~)~'], $value ); }); - $tmp = $this->runSnippet($name, array_merge($this->config, array( + $tmp = $this->runSnippet($name, array_merge($this->config, [ 'pdoTools' => $this, 'pdoFetch' => $this, 'row' => $row, - ))); + ])); if (!is_array($tmp)) { $tmp = ($tmp[0] == '[' || $tmp[0] == '{') @@ -1204,8 +1025,8 @@ public function prepareRow($row = array()) array_walk_recursive($row, function (&$value) { $value = str_replace( - array('*(*(*(*(*(*', '*)*)*)*)*)*', '~(~(~(~(~(~', '~)~)~)~)~)~'), - array('[', ']', '{', '}'), + ['*(*(*(*(*(*', '*)*)*)*)*)*', '~(~(~(~(~(~', '~)~)~)~)~)~'], + ['[', ']', '{', '}'], $value ); }); @@ -1222,9 +1043,9 @@ public function prepareRow($row = array()) * * @return array */ - public function checkPermissions($rows = array()) + public function checkPermissions(array $rows = []) { - $permissions = array(); + $permissions = []; if (!empty($this->config['checkPermissions'])) { $tmp = array_map('trim', explode(',', $this->config['checkPermissions'])); foreach ($tmp as $v) { @@ -1264,7 +1085,7 @@ public function checkPermissions($rows = array()) * * @return mixed */ - public function getCache($options = array()) + public function getCache($options = []) { $cacheKey = $this->getCacheKey($options); $cacheOptions = $this->getCacheOptions($options); @@ -1292,7 +1113,7 @@ public function getCache($options = array()) * * @return string $cacheKey */ - public function setCache($data = array(), $options = array()) + public function setCache($data = [], $options = []) { $cacheKey = $this->getCacheKey($options); $cacheOptions = $this->getCacheOptions($options); @@ -1321,9 +1142,10 @@ public function clearFileCache() if (is_dir($dir)) { $list = scandir($dir); foreach ($list as $file) { - if ($file[0] == '.') { + if ($file[0] === '.') { continue; - } elseif (is_file($dir . '/' . $file)) { + } + if (is_file($dir . '/' . $file)) { @unlink($dir . '/' . $file); $count++; } @@ -1341,7 +1163,7 @@ public function clearFileCache() * * @return mixed|string */ - public function makeUrl($id, $options = array(), $args = array()) + public function makeUrl($id, $options = [], $args = []) { $scheme = !empty($options['scheme']) ? $options['scheme'] @@ -1365,7 +1187,7 @@ public function makeUrl($id, $options = array(), $args = array()) } else { $context = ''; } - if (strtolower($scheme) == 'uri') { + if (strtolower($scheme) === 'uri') { $scheme = -1; } $url = $this->modx->makeUrl($id, $context, $args, $scheme, $options); @@ -1382,18 +1204,18 @@ public function makeUrl($id, $options = array(), $args = array()) * * @return array */ - protected function getCacheOptions($options = array()) + protected function getCacheOptions($options = []) { if (empty($options)) { $options = $this->config; } - $cacheOptions = array( + $cacheOptions = [ xPDO::OPT_CACHE_KEY => !empty($options['cache_key']) || !empty($options['cacheKey']) - ? 'default' + ? 'pdotools' : (!empty($this->modx->resource) ? $this->modx->getOption('cache_resource_key', null, 'resource') - : 'default'), + : 'pdotools'), xPDO::OPT_CACHE_HANDLER => !empty($options['cache_handler']) ? $options['cache_handler'] @@ -1402,7 +1224,7 @@ protected function getCacheOptions($options = array()) xPDO::OPT_CACHE_EXPIRES => isset($options['cacheTime']) && $options['cacheTime'] !== '' ? (integer)$options['cacheTime'] : (integer)$this->modx->getOption('cache_resource_expires', null, 0), - ); + ]; return $cacheOptions; } @@ -1415,7 +1237,7 @@ protected function getCacheOptions($options = array()) * * @return bool|string */ - protected function getCacheKey($options = array()) + protected function getCacheKey($options = []) { if (empty($options)) { $options = $this->config; @@ -1432,7 +1254,7 @@ protected function getCacheKey($options = array()) : ''; if (is_array($options)) { $options['cache_user'] = isset($options['cache_user']) - ? (integer)$options['cache_user'] + ? (int)$options['cache_user'] : $this->modx->user->id; } @@ -1443,14 +1265,14 @@ protected function getCacheKey($options = array()) /** * Flatten array of placeholders with nested arrays * - * @param $array + * @param array $array * @param string $plPrefix * * @return array */ - protected function flattenArray($array, $plPrefix = '') + protected function flattenArray(array $array, $plPrefix = '') { - $result = array(); + $result = []; foreach ($array as $k => $v) { if (is_array($v)) { @@ -1471,7 +1293,7 @@ protected function flattenArray($array, $plPrefix = '') * @param $filter * @param array $properties */ - public function debugParserModifier($value, $filter, $properties = array()) + public function debugParserModifier($value, $filter, $properties = []) { if (is_array($value)) { $value = trim(print_r($value, true)); @@ -1490,11 +1312,11 @@ public function debugParserModifier($value, $filter, $properties = array()) /** * Log Fenom method call * - * @param $method - * @param $name + * @param string $method + * @param string $name * @param array $properties */ - public function debugParserMethod($method, $name, $properties = array()) + public function debugParserMethod($method, $name, array $properties = []) { if (is_array($name)) { $name = trim(print_r($name, true)); @@ -1523,23 +1345,23 @@ protected function debugParser($tag) $hash = sha1($tag); if (!isset($this->tags[$hash])) { - $this->tags[$hash] = array( + $this->tags[$hash] = [ 'queries' => $this->modx->executedQueries, 'queries_time' => $this->modx->queryTime, 'parse_time' => microtime(true), - ); + ]; } else { $queries = $this->modx->executedQueries - $this->tags[$hash]['queries']; $queries_time = number_format(round($this->modx->queryTime - $this->tags[$hash]['queries_time'], 7), 7); $parse_time = number_format(round(microtime(true) - $this->tags[$hash]['parse_time'], 7), 7); if (!isset($parser->tags[$hash])) { - $parser->tags[$hash] = array( + $parser->tags[$hash] = [ 'tag' => $tag, 'attempts' => 1, 'queries' => $queries, 'queries_time' => $queries_time, 'parse_time' => $parse_time, - ); + ]; } else { $parser->tags[$hash]['attempts'] += 1; $parser->tags[$hash]['queries'] += $queries; @@ -1559,9 +1381,9 @@ protected function debugParser($tag) private function isAllowedFileExtension($extension, $type = '') { switch ($type) { - case 'modChunk': + case 'modChunk': $result = in_array($extension, $this->config['chunkExtensions'], true); - break; + break; case 'modSnippet': $result = $extension === 'php'; break; diff --git a/core/components/pdotools/model/pdotools/pdofetch.class.php b/core/components/pdotools/src/Fetch.php similarity index 77% rename from core/components/pdotools/model/pdotools/pdofetch.class.php rename to core/components/pdotools/src/Fetch.php index 96740576..50377e9f 100644 --- a/core/components/pdotools/model/pdotools/pdofetch.class.php +++ b/core/components/pdotools/src/Fetch.php @@ -1,15 +1,24 @@ 'modResource', - 'limit' => 10, - 'sortby' => '', - 'sortdir' => '', - 'groupby' => '', - 'totalVar' => 'total', - 'setTotal' => false, - 'tpl' => '', - 'return' => 'chunks', // chunks, data, sql or ids - - 'select' => '', - 'leftJoin' => '', - 'rightJoin' => '', - 'innerJoin' => '', - - 'includeTVs' => '', - 'tvPrefix' => '', - 'tvsJoin' => array(), - 'tvsSelect' => array(), - - 'tvFiltersAndDelimiter' => ',', - 'tvFiltersOrDelimiter' => '||', - - 'additionalPlaceholders' => '', - 'useWeblinkUrl' => false, - ), $config), - $clean_timings); + $config += [ + 'class' => modResource::class, + 'limit' => 10, + 'sortby' => '', + 'sortdir' => '', + 'groupby' => '', + 'totalVar' => 'total', + 'setTotal' => false, + 'tpl' => '', + 'return' => 'chunks', // chunks, data, sql or ids + + 'select' => '', + 'leftJoin' => '', + 'rightJoin' => '', + 'innerJoin' => '', + + 'includeTVs' => '', + 'tvPrefix' => '', + 'tvsJoin' => [], + 'tvsSelect' => [], + + 'tvFiltersAndDelimiter' => ',', + 'tvFiltersOrDelimiter' => '||', + + 'additionalPlaceholders' => '', + 'useWeblinkUrl' => false, + ]; + parent::setConfig($config, $clean_timings); if (empty($this->config['class'])) { - $this->config['class'] = 'modResource'; + $this->config['class'] = modResource::class; } $this->loadModels(); $this->ancestry = $this->modx->getAncestry($this->config['class']); @@ -105,29 +113,28 @@ public function run() $this->addTime('Rows fetched'); $rows = $this->checkPermissions($rows); $this->count = count($rows); - - if (strtolower($this->config['return']) == 'ids') { - $ids = array(); + if (strtolower($this->config['return']) === 'ids') { + $ids = []; foreach ($rows as $row) { $ids[] = $row[$this->pk]; } $output = implode(',', $ids); - } elseif (strtolower($this->config['return']) == 'data') { + } elseif (strtolower($this->config['return']) === 'data') { $rows = $this->prepareRows($rows); $this->addTime('Returning raw data'); $output = &$rows; - } elseif (strtolower($this->config['return']) == 'json') { + } elseif (strtolower($this->config['return']) === 'json') { $rows = $this->prepareRows($rows); $this->addTime('Returning raw data as JSON string'); $output = json_encode($rows); - } elseif (strtolower($this->config['return']) == 'serialize') { + } elseif (strtolower($this->config['return']) === 'serialize') { $rows = $this->prepareRows($rows); $this->addTime('Returning raw data as serialized string'); $output = serialize($rows); } else { $rows = $this->prepareRows($rows); $time = microtime(true); - $output = array(); + $output = []; foreach ($rows as $row) { if (!empty($this->config['additionalPlaceholders'])) { $row = array_merge($this->config['additionalPlaceholders'], $row); @@ -139,7 +146,7 @@ public function run() if (!isset($row['context_key'])) { $row['context_key'] = ''; } - if (isset($row['class_key']) && ($row['class_key'] == 'modWebLink')) { + if (isset($row['class_key']) && ($row['class_key'] === modWebLink::class)) { $row['link'] = isset($row['content']) && is_numeric(trim($row['content'], '[]~ ')) ? $this->makeUrl((int)trim($row['content'], '[]~ '), $row) : (isset($row['content']) ? $row['content'] : ''); @@ -151,7 +158,7 @@ public function run() } $tpl = $this->defineChunk($row); - if (isset($row['sessionid']) && $this->modx->getOption('pdotools_remove_user_sensitive_data', null, true)) { + if ($this->modx->getOption('pdotools_remove_user_sensitive_data', null, true)) { $row = array_diff_key( $row, ['sessionid' => 1, 'password' => 1, 'cachepwd' => 1, 'salt' => 1, 'session_stale' => 1, 'remote_key' => 1, 'remote_data' => 1, 'hash_class' => 1] @@ -173,9 +180,9 @@ public function run() } } } else { - $this->modx->log(modX::LOG_LEVEL_INFO, '[pdoTools] ' . $this->query->toSQL()); + $this->modx->log(xPDO::LOG_LEVEL_INFO, '[pdoTools] ' . $this->query->toSQL()); $errors = $this->query->stmt->errorInfo(); - $this->modx->log(modX::LOG_LEVEL_ERROR, '[pdoTools] Error ' . $errors[0] . ': ' . $errors[2]); + $this->modx->log(xPDO::LOG_LEVEL_ERROR, '[pdoTools] Error ' . $errors[0] . ': ' . $errors[2]); $this->addTime('Could not process query, error #' . $errors[1] . ': ' . $errors[2]); } } @@ -201,21 +208,21 @@ public function makeQuery() public function addWhere() { $time = microtime(true); - $where = array(); + $where = []; if (!empty($this->config['where'])) { $tmp = $this->config['where']; - if (is_string($tmp) && ($tmp[0] == '{' || $tmp[0] == '[')) { + if (is_string($tmp) && ($tmp[0] === '{' || $tmp[0] === '[')) { $tmp = json_decode($tmp, true); } if (!is_array($tmp)) { - $tmp = array($tmp); + $tmp = [$tmp]; } $where = $this->replaceTVCondition($tmp); } $where = $this->additionalConditions($where); if (!empty($where)) { $this->query->where($where); - $condition = array(); + $condition = []; foreach ($where as $k => $v) { if (is_array($v)) { if (isset($v[0])) { @@ -234,16 +241,16 @@ public function addWhere() $time = microtime(true); if (!empty($this->config['having'])) { $tmp = $this->config['having']; - if (is_string($tmp) && ($tmp[0] == '{' || $tmp[0] == '[')) { + if (is_string($tmp) && ($tmp[0] === '{' || $tmp[0] === '[')) { $tmp = json_decode($tmp, true); } if (!is_array($tmp)) { - $tmp = array($tmp); + $tmp = [$tmp]; } $having = $this->replaceTVCondition($tmp); $this->query->having($having); - $condition = array(); + $condition = []; foreach ($having as $k => $v) { if (is_array($v)) { $condition[] = $k . '(' . implode(',', $v) . ')'; @@ -261,7 +268,7 @@ public function addWhere() */ public function setTotal() { - if ($this->config['setTotal'] && !in_array($this->config['return'], array('sql', 'ids'))) { + if ($this->config['setTotal'] && !in_array($this->config['return'], ['sql', 'ids'])) { $time = microtime(true); $q = $this->modx->prepare("SELECT FOUND_ROWS();"); @@ -290,7 +297,7 @@ public function addJoins() $this->config['leftJoin'] = '[]'; } - $joinSequence = array('innerJoin', 'leftJoin', 'rightJoin'); + $joinSequence = ['innerJoin', 'leftJoin', 'rightJoin']; if (!empty($this->config['joinSequence'])) { if (is_string($this->config['joinSequence'])) { $this->config['joinSequence'] = array_map('trim', explode(',', $this->config['joinSequence'])); @@ -303,7 +310,7 @@ public function addJoins() foreach ($joinSequence as $join) { if (!empty($this->config[$join])) { $tmp = $this->config[$join]; - if (is_string($tmp) && ($tmp[0] == '{' || $tmp[0] == '[')) { + if (is_string($tmp) && ($tmp[0] === '{' || $tmp[0] === '[')) { $tmp = json_decode($tmp, true); } if ($join == 'leftJoin' && !empty($this->config['tvsJoin'])) { @@ -311,8 +318,8 @@ public function addJoins() } foreach ($tmp as $k => $v) { $class = !empty($v['class']) ? $v['class'] : $k; - $alias = !empty($v['alias']) ? $v['alias'] : $k; - $on = !empty($v['on']) ? $v['on'] : array(); + $alias = $this->modx->getAlias(!empty($v['alias']) ? $v['alias'] : $k); + $on = !empty($v['on']) ? $v['on'] : []; if (!is_numeric($alias) && !is_numeric($class)) { $this->query->$join($class, $alias, $on); $this->addTime($join . 'ed ' . $class . ' as ' . $alias . '', @@ -336,37 +343,40 @@ public function addSelects() { $time = microtime(true); + $alias = $this->modx->getAlias($this->config['class']); + if ($this->config['return'] == 'ids') { - $this->query->select('`' . $this->config['class'] . '`.`' . $this->pk . '`'); + $this->query->select("`{$alias}`.`{$this->pk}`"); $this->addTime('Parameter "return" set to "ids", so we select only primary key', microtime(true) - $time); } elseif ($tmp = $this->config['select']) { if (!is_array($tmp)) { - $tmp = (!empty($tmp) && ($tmp[0] == '{' || $tmp[0] == '[')) + $tmp = (!empty($tmp) && ($tmp[0] === '{' || $tmp[0] === '[')) ? json_decode($tmp, true) - : array($this->config['class'] => $tmp); + : [$alias => $tmp]; } if (!is_array($tmp)) { - $tmp = array(); + $tmp = []; } $tmp = array_merge($tmp, $this->config['tvsSelect']); $i = 0; - foreach ($tmp as $class => $fields) { - if (is_numeric($class)) { - $class = $alias = $this->config['class']; - } elseif (isset($this->aliases[$class])) { - $alias = $class; + foreach ($tmp as $alias => $fields) { + if (is_numeric($alias)) { + $class = $this->config['class']; + $alias = $this->modx->getAlias($class); + } elseif (isset($this->aliases[$alias])) { $class = $this->aliases[$alias]; } else { - $alias = $class; + $class = class_exists('MODX\Revolution\\' . $alias) + ? 'MODX\Revolution\\' . $alias + : $alias; + $alias = $this->modx->getAlias($class); } - if (is_string($fields) && !preg_match('/\b' . $alias . '\b|\bAS\b|\(|`/i', - $fields) && isset($this->modx->map[$class]) - ) { + + if (is_string($fields) && !preg_match('/\b' . $alias . '\b|\bAS\b|\(|`/i', $fields)) { if ($fields == 'all' || $fields == '*' || empty($fields)) { $fields = $this->modx->getSelectColumns($class, $alias); } else { - $fields = $this->modx->getSelectColumns($class, $alias, '', - array_map('trim', explode(',', $fields))); + $fields = $this->modx->getSelectColumns($class, $alias, '', array_map('trim', explode(',', $fields))); } } @@ -376,7 +386,7 @@ public function addSelects() if (is_string($fields) && strpos($fields, '(') !== false) { // Commas in functions - $fields = preg_replace_callback('/\(.*?\)/', function($matches) { + $fields = preg_replace_callback('/\(.*?\)/', function ($matches) { return str_replace(",", "|", $matches[0]); }, $fields); $fields = explode(',', $fields); @@ -384,15 +394,13 @@ public function addSelects() $field = str_replace('|', ',', $field); } $this->query->select($fields); - $this->addTime('Added selection of ' . $class . ': ' . str_replace('`' . $alias . '`.', - '', implode(',', $fields)) . '', microtime(true) - $time); + $this->addTime('Added selection of ' . $alias . ': ' . str_replace('`' . $alias . '`.', '', implode(',', $fields)) . '', microtime(true) - $time); } else { $this->query->select($fields); if (is_array($fields)) { $fields = current($fields) . ' AS ' . current(array_flip($fields)); } - $this->addTime('Added selection of ' . $class . ': ' . str_replace('`' . $alias . '`.', - '', $fields) . '', microtime(true) - $time); + $this->addTime('Added selection of ' . $alias . ': ' . str_replace('`' . $alias . '`.', '', $fields) . '', microtime(true) - $time); } $i++; @@ -406,7 +414,7 @@ public function addSelects() unset($columns[$key]); } } - $this->config['select'] = array($this->config['class'] => implode(',', $columns)); + $this->config['select'] = [$this->config['class'] => implode(',', $columns)]; $this->addSelects(); } } @@ -432,25 +440,26 @@ public function addGrouping() public function addSort() { $time = microtime(true); + $alias = $this->modx->getAlias($this->config['class']); $tmp = $this->config['sortby']; - if (empty($tmp) || (is_string($tmp) && in_array(strtolower($tmp), array('resources', 'ids')))) { - $resources = $this->config['class'] . '.' . $this->pk . ':IN'; + if (empty($tmp) || (is_string($tmp) && in_array(strtolower($tmp), ['resources', 'ids']))) { + $resources = $alias . '.' . $this->pk . ':IN'; if (!empty($this->config['where'][$resources])) { - $tmp = array( - 'FIELD(`' . $this->config['class'] . '`.`' . $this->pk . '`,\'' . implode('\',\'', + $tmp = [ + 'FIELD(`' . $alias . '`.`' . $this->pk . '`,\'' . implode('\',\'', $this->config['where'][$resources]) . '\')' => '', - ); + ]; } else { - $tmp = array( - $this->config['class'] . '.' . $this->pk => !empty($this->config['sortdir']) + $tmp = [ + $alias . '.' . $this->pk => !empty($this->config['sortdir']) ? $this->config['sortdir'] : 'ASC', - ); + ]; } } elseif (is_string($tmp)) { - $tmp = $tmp[0] == '{' || $tmp[0] == '[' + $tmp = $tmp[0] === '{' || $tmp[0] === '[' ? json_decode($tmp, true) - : array($tmp => $this->config['sortdir']); + : [$tmp => $this->config['sortdir']]; } if (!empty($this->config['sortbyTV']) && !array_key_exists($this->config['sortbyTV'], $tmp)) { $tmp2[$this->config['sortbyTV']] = !empty($this->config['sortdirTV']) @@ -497,7 +506,7 @@ public function addSort() } } } elseif (array_key_exists($sortby, $fields)) { - $sortby = $this->config['class'] . '.' . $sortby; + $sortby = $alias . '.' . $sortby; } // Escaping of columns names $tmp = explode(',', $sortby); @@ -507,23 +516,19 @@ public function addSort() } }); $sortby = implode(',', $tmp); - if (!in_array(strtoupper($sortdir), array('ASC', 'DESC', ''), true)) { + if (!in_array(strtoupper($sortdir), ['ASC', 'DESC', ''], true)) { $sortdir = 'ASC'; } - // Use reflection to check clause by protected method of xPDOQuery - $isValidClause = new ReflectionMethod('xPDOQuery', 'isValidClause'); - $isValidClause->setAccessible(true); - $isValidClause->invoke($this->query, $sortby); - if (!$isValidClause->invoke($this->query, $sortby)) { + if (!xPDOQuery::isValidClause($sortby)) { $message = 'SQL injection attempt detected in sortby column; clause rejected'; $this->modx->log(xPDO::LOG_LEVEL_ERROR, $message); $this->addTime($message . ': ' . $sortby); } elseif (!empty($sortby)) { - $this->query->query['sortby'][] = array( + $this->query->query['sortby'][] = [ 'column' => $sortby, - 'direction' => $sortdir - ); + 'direction' => $sortdir, + ]; $this->addTime('Sorted by ' . $sortby . ', ' . $sortdir . '', microtime(true) - $time); } } @@ -573,37 +578,39 @@ public function addTVs() $class = !empty($this->config['joinTVsTo']) ? $this->config['joinTVsTo'] : $this->config['class']; - $subclass = preg_grep('#^' . $class . '#i', $this->modx->classMap['modResource']); - if (!preg_match('#^modResource$#i', $class) && !count($subclass)) { - $this->modx->log(modX::LOG_LEVEL_ERROR, + $alias = $this->modx->getAlias($class); + if ($alias !== 'modResource' && !in_array($class, $this->modx->classMap[modResource::class])) { + $this->modx->log( + xPDO::LOG_LEVEL_ERROR, '[pdoTools] Could not join TVs to the class "' . $class . '" that is not a subclass of the "modResource". Try to specify correct class in the "joinTVsTo" parameter.'); - } else { - $tvs = array_map('trim', explode(',', $includeTVs)); - $tvs = array_unique($tvs); - if (!empty($tvs)) { - $q = $this->modx->newQuery('modTemplateVar', array('name:IN' => $tvs)); - $q->select('id,name,type,default_text'); - $tstart = microtime(true); - if ($q->prepare() && $q->stmt->execute()) { - $this->modx->queryTime += microtime(true) - $tstart; - $this->modx->executedQueries++; - $tvs = array(); - while ($tv = $q->stmt->fetch(PDO::FETCH_ASSOC)) { - $name = strtolower($tv['name']); - $alias = 'TV' . $name; - $this->config['tvsJoin'][$name] = array( - 'class' => 'modTemplateVarResource', - 'alias' => $alias, - 'on' => '`TV' . $name . '`.`contentid` = `' . $class . '`.`id` AND `TV' . $name . '`.`tmplvarid` = ' . $tv['id'], - 'tv' => $tv, - ); - $this->config['tvsSelect'][$alias] = array('`' . $tvPrefix . $tv['name'] . '`' => 'IFNULL(`' . $alias . '`.`value`, ' . $this->modx->quote($tv['default_text']) . ')'); - $tvs[] = $tv['name']; - } - $this->addTime('Included list of tvs: ' . implode(', ', $tvs) . '', - microtime(true) - $time); + return; + } + + $tvs = array_map('trim', explode(',', $includeTVs)); + $tvs = array_unique($tvs); + if (!empty($tvs)) { + $q = $this->modx->newQuery(modTemplateVar::class, ['name:IN' => $tvs]); + $q->select('id,name,type,default_text'); + $tstart = microtime(true); + if ($q->prepare() && $q->stmt->execute()) { + $this->modx->queryTime += microtime(true) - $tstart; + $this->modx->executedQueries++; + $tvs = []; + while ($tv = $q->stmt->fetch(PDO::FETCH_ASSOC)) { + $name = strtolower($tv['name']); + $alias_tv = 'TV' . $name; + $this->config['tvsJoin'][$name] = [ + 'class' => modTemplateVarResource::class, + 'alias' => $alias_tv, + 'on' => "`{$alias_tv}`.`contentid` = `{$alias}`.`id` AND `{$alias_tv}`.`tmplvarid` = {$tv['id']}", + 'tv' => $tv, + ]; + $this->config['tvsSelect'][$alias_tv] = ["`{$tvPrefix}{$tv['name']}`" => "IFNULL(`{$alias_tv}`.`value`, {$this->modx->quote($tv['default_text'])})"]; + $tvs[] = $tv['name']; } + + $this->addTime('Included list of tvs: ' . implode(', ', $tvs) . '', microtime(true) - $time); } } } @@ -617,18 +624,19 @@ public function addTVs() * * @return array */ - public function additionalConditions($where = array()) + public function additionalConditions($where = []) { $config = $this->config; $class = $this->config['class']; + $alias = $this->modx->getAlias($this->config['class']); // These rules works only for descendants of modResource - if (!in_array('modResource', $this->ancestry) || !empty($config['disableConditions'])) { + if (!in_array(modResource::class, $this->ancestry) || !empty($config['disableConditions'])) { return $where; } $time = microtime(true); - $params = array( + $params = [ 'resources' => 'id', 'parents' => 'parent', 'templates' => 'template', @@ -638,7 +646,7 @@ public function additionalConditions($where = array()) 'hideContainers' => 'isfolder', 'hideUnsearchable' => 'searchable', 'context' => 'context_key', - ); + ]; // Exclude parameters that may already have been processed foreach ($params as $param => $field) { @@ -646,19 +654,19 @@ public function additionalConditions($where = array()) if (isset($config[$param])) { foreach ($where as $k => $v) { // Usual condition - if (!is_numeric($k) && strpos($k, $field) === 0 || strpos($k, $class . '.' . $field) !== false) { + if (!is_numeric($k) && strpos($k, $field) === 0 || strpos($k, $alias . '.' . $field) !== false) { $found = true; break; } // Array of conditions elseif (is_numeric($k) && is_array($v)) { foreach ($v as $k2 => $v2) { - if (strpos($k2, $field) === 0 || strpos($k2, $class . '.' . $field) !== false) { + if (strpos($k2, $field) === 0 || strpos($k2, $alias . '.' . $field) !== false) { $found = true; break(2); } } } // Raw SQL string - elseif (is_numeric($k) && strpos($v, $class) !== false && preg_match('/\b' . $field . '\b/i', $v)) { + elseif (is_numeric($k) && strpos($v, $alias) !== false && preg_match('/\b' . $field . '\b/i', $v)) { $found = true; break; } @@ -678,37 +686,37 @@ public function additionalConditions($where = array()) switch ($param) { case 'showUnpublished': if (empty($value)) { - $where[$class . '.published'] = 1; + $where[$alias . '.published'] = 1; } break; case 'showHidden': if (empty($value)) { - $where[$class . '.hidemenu'] = 0; + $where[$alias . '.hidemenu'] = 0; } break; case 'showDeleted': if (empty($value)) { - $where[$class . '.deleted'] = 0; + $where[$alias . '.deleted'] = 0; } break; case 'hideContainers': if (!empty($value)) { - $where[$class . '.isfolder'] = 0; + $where[$alias . '.isfolder'] = 0; } break; case 'hideUnsearchable': if (!empty($value)) { - $where[$class . '.searchable'] = 1; + $where[$alias . '.searchable'] = 1; } break; case 'context': if (!empty($value)) { $context = array_map('trim', explode(',', $value)); if (!empty($context) && is_array($context)) { - if (count($context) == 1) { - $where[$class . '.context_key'] = $context[0]; + if (count($context) === 1) { + $where[$alias . '.context_key'] = $context[0]; } else { - $where[$class . '.context_key:IN'] = $context; + $where[$alias . '.context_key:IN'] = $context; } } } @@ -716,7 +724,7 @@ public function additionalConditions($where = array()) case 'resources': if (!empty($value)) { $resources = array_map('trim', explode(',', $value)); - $resources_in = $resources_out = array(); + $resources_in = $resources_out = []; foreach ($resources as $v) { if (!is_numeric($v)) { continue; @@ -728,22 +736,22 @@ public function additionalConditions($where = array()) } } if (!empty($resources_in)) { - $where[$class . '.id:IN'] = $resources_in; + $where[$alias . '.id:IN'] = $resources_in; } if (!empty($resources_out)) { - $where[$class . '.id:NOT IN'] = $resources_out; + $where[$alias . '.id:NOT IN'] = $resources_out; } } break; case 'parents': if (!empty($value)) { $parents = array_map('trim', explode(',', $value)); - $parents_in = $parents_out = array(); + $parents_in = $parents_out = []; foreach ($parents as $v) { if (!is_numeric($v)) { continue; } - if ($v[0] == '-') { + if ($v[0] === '-') { $parents_out[] = abs($v); } else { $parents_in[] = abs($v); @@ -753,9 +761,8 @@ public function additionalConditions($where = array()) ? (int)$config['depth'] : 10; if (!empty($depth) && $depth > 0) { - $pids = array(); - $q = $this->modx->newQuery($class, - array('id:IN' => array_merge($parents_in, $parents_out))); + $pids = []; + $q = $this->modx->newQuery($class, ['id:IN' => array_merge($parents_in, $parents_out)]); $q->select('id,context_key'); $tstart = microtime(true); if ($q->prepare() && $q->stmt->execute()) { @@ -770,29 +777,26 @@ public function additionalConditions($where = array()) continue; } elseif (in_array($k, $parents_in)) { $parents_in = array_merge($parents_in, - $this->modx->getChildIds($k, $depth, array('context' => $v))); + $this->modx->getChildIds($k, $depth, ['context' => $v])); } else { $parents_out = array_merge($parents_out, - $this->modx->getChildIds($k, $depth, array('context' => $v))); + $this->modx->getChildIds($k, $depth, ['context' => $v])); } } if (empty($parents_in)) { - $parents_in = $this->modx->getChildIds(0, $depth, - array('context' => $this->config['context'])); + $parents_in = $this->modx->getChildIds(0, $depth, ['context' => $this->config['context']]); } } // Support of miniShop2 categories - $members = array(); - if (in_array('msCategory', $this->modx->classMap['modResource']) && - empty($this->config['disableMS2']) - ) { + $members = []; + if (in_array('msCategory', $this->modx->classMap[modResource::class]) && empty($this->config['disableMS2'])) { if (!empty($parents_in) || !empty($parents_out)) { $q = $this->modx->newQuery('msCategoryMember'); if (!empty($parents_in)) { - $q->where(array('category_id:IN' => $parents_in)); + $q->where(['category_id:IN' => $parents_in]); } if (!empty($parents_out)) { - $q->where(array('category_id:NOT IN' => $parents_out)); + $q->where(['category_id:NOT IN' => $parents_out]); } $q->select('product_id'); $tstart = microtime(true); @@ -808,32 +812,32 @@ public function additionalConditions($where = array()) if (!empty($this->config['includeParents'])) { $members = array_merge($members, $parents_in); } - $where[] = array( - $class . '.parent:IN' => $parents_in, - 'OR:' . $class . '.id:IN' => $members, - ); + $where[] = [ + $alias . '.parent:IN' => $parents_in, + 'OR:' . $alias . '.id:IN' => $members, + ]; } elseif (!empty($parents_in) && !empty($this->config['includeParents'])) { - $where[] = array( - $class . '.parent:IN' => $parents_in, - 'OR:' . $class . '.id:IN' => $parents_in, - ); + $where[] = [ + $alias . '.parent:IN' => $parents_in, + 'OR:' . $alias . '.id:IN' => $parents_in, + ]; } elseif (!empty($parents_in)) { - $where[$class . '.parent:IN'] = $parents_in; + $where[$alias . '.parent:IN'] = $parents_in; } if (!empty($parents_out) && !empty($this->config['includeParents'])) { - $where[] = array( - $class . '.parent:NOT IN' => $parents_out, - 'AND:' . $class . '.id:NOT IN' => $parents_out, - ); + $where[] = [ + $alias . '.parent:NOT IN' => $parents_out, + 'AND:' . $alias . '.id:NOT IN' => $parents_out, + ]; } elseif (!empty($parents_out)) { - $where[$class . '.parent:NOT IN'] = $parents_out; + $where[$alias . '.parent:NOT IN'] = $parents_out; } } break; case 'templates': if (!empty($value)) { $templates = array_map('trim', explode(',', $value)); - $templates_in = $templates_out = array(); + $templates_in = $templates_out = []; foreach ($templates as $v) { if (!is_numeric($v)) { continue; @@ -845,10 +849,10 @@ public function additionalConditions($where = array()) } } if (!empty($templates_in)) { - $where[$class . '.template:IN'] = $templates_in; + $where[$alias . '.template:IN'] = $templates_in; } if (!empty($templates_out)) { - $where[$class . '.template:NOT IN'] = $templates_out; + $where[$alias . '.template:NOT IN'] = $templates_out; } } break; @@ -877,7 +881,7 @@ public function addTVFilters() $tvFiltersOrDelimiter = $this->config['tvFiltersOrDelimiter']; $tvFilters = array_map('trim', explode($tvFiltersOrDelimiter, $this->config['tvFilters'])); - $operators = array( + $operators = [ '<=>' => '<=>', '===' => '=', '!==' => '!=', @@ -890,25 +894,25 @@ public function addTVFilters() '>>' => '>', '>=' => '>=', '=>' => '=>', - ); + ]; $includeTVs = !empty($this->config['includeTVs']) ? array_map('trim', explode(',', $this->config['includeTVs'])) - : array(); - $where = array(); + : []; + $where = []; if (!empty($this->config['where'])) { $tmp = $this->config['where']; if (is_string($tmp) && ($tmp[0] == '{' || $tmp[0] == '[')) { $where = json_decode($tmp, true); } if (!is_array($where)) { - $where = array($where); + $where = [$where]; } } - $conditions = array(); + $conditions = []; foreach ($tvFilters as $tvFilter) { - $condition = array(); + $condition = []; $filters = explode($tvFiltersAndDelimiter, $tvFilter); foreach ($filters as $filter) { $operator = '=='; @@ -961,10 +965,10 @@ public function replaceTVCondition(array $array) $time = microtime(true); $tvs = implode('|', array_keys($this->config['tvsJoin'])); - $sorts = array(); + $sorts = []; foreach ($array as $k => $v) { - $callback = function($matches) { - return '`TV' . strtolower($matches[1]). '`.`value`'; + $callback = function ($matches) { + return '`TV' . strtolower($matches[1]) . '`.`value`'; }; if (is_numeric($k) && is_string($v)) { $tmp = preg_replace_callback('/\b(' . $tvs . ')\b/i', $callback, $v); @@ -991,7 +995,7 @@ public function replaceTVCondition(array $array) * * @return array */ - public function getObject($class, $where = '', $config = array()) + public function getObject($class, $where = '', $config = []) { return $this->getArray($class, $where, $config); } @@ -1007,37 +1011,29 @@ public function getObject($class, $where = '', $config = array()) * * @return array */ - public function getArray($class, $where = '', $config = array()) + public function getArray($class, $where = '', $config = []) { $config['limit'] = 1; $rows = $this->getCollection($class, $where, $config); return !empty($rows[0]) ? $rows[0] - : array(); + : []; } /** * PDO replacement for modX::getCollection() * - * @param $class - * @param string $where + * @param string $class + * @param string|int|array $where * @param array $config * * @return array|boolean */ - public function getCollection($class, $where = '', $config = array()) + public function getCollection($class, $where = '', array $config = []) { - /** @var pdoFetch $instance */ - $fqn = $this->modx->getOption('pdoFetch.class', null, 'pdotools.pdofetch', true); - $path = $this->modx->getOption('pdofetch_class_path', null, MODX_CORE_PATH . 'components/pdotools/model/', - true); - if ($pdoClass = $this->modx->loadClass($fqn, $path, false, true)) { - $instance = new $pdoClass($this->modx, $config); - } else { - return false; - } + $instance = new self($this->modx, $config, $this->fenom); $config['class'] = $class; $config['limit'] = !isset($config['limit']) @@ -1046,8 +1042,8 @@ public function getCollection($class, $where = '', $config = array()) if (!empty($where)) { unset($config['where']); if (is_numeric($where)) { - $where = array($instance->modx->getPK($class) => (int)$where); - } elseif (is_string($where) && ($where[0] == '{' || $where[0] == '[')) { + $where = [$instance->modx->getPK($class) => (int)$where]; + } elseif (is_string($where) && ($where[0] === '{' || $where[0] === '[')) { $where = json_decode($where, true); } if (is_array($where)) { @@ -1076,7 +1072,7 @@ public function getCollection($class, $where = '', $config = array()) $instance->modx->executedQueries++; $tstart = microtime(true); if (!$rows = $instance->query->stmt->fetchAll(PDO::FETCH_ASSOC)) { - $rows = array(); + $rows = []; } else { $rows = $instance->checkPermissions($rows); $rows = $instance->prepareRows($rows); @@ -1106,12 +1102,12 @@ public function getCollection($class, $where = '', $config = array()) * * @return array */ - public function getChildIds($class, $id, $depth = 10, array $options = array()) + public function getChildIds($class, $id, $depth = 10, array $options = []) { - $ids = array(); + $ids = []; $where = isset($options['where']) && is_array($options['where']) ? $options['where'] - : array(); + : []; $id_field = !empty($options['id_field']) ? $options['id_field'] : 'id'; @@ -1136,5 +1132,4 @@ public function getChildIds($class, $id, $depth = 10, array $options = array()) return $ids; } - } diff --git a/core/components/pdotools/model/pdotools/_fenom.php b/core/components/pdotools/src/Parsing/Fenom/Fenom.php similarity index 72% rename from core/components/pdotools/model/pdotools/_fenom.php rename to core/components/pdotools/src/Parsing/Fenom/Fenom.php index 3645aa83..ae09ed34 100644 --- a/core/components/pdotools/model/pdotools/_fenom.php +++ b/core/components/pdotools/src/Parsing/Fenom/Fenom.php @@ -1,95 +1,203 @@ pdoTools = $pdoTools; + $this->modx = $modx; - parent::__construct($provider); + $provider = new Chunk($modx, $pdoTools); - $this->setCompileDir(rtrim($pdoTools->config['cachePath'], '/') . '/file'); - $this->addProvider('template', new modTemplateProvider($pdoTools)); - $this->addProvider('file', new modFileProvider($pdoTools)); + parent::__construct($provider); - $default_options = array( - 'disable_cache' => !$pdoTools->config['useFenomCache'], - 'force_compile' => !$pdoTools->config['useFenomCache'], - 'force_include' => !$pdoTools->config['useFenomCache'], - 'auto_reload' => $pdoTools->config['useFenomCache'], - ); - if ($options = json_decode($pdoTools->modx->getOption('pdotools_fenom_options'), true)) { + $this->setCompileDir(rtrim($pdoTools->config('cachePath'), '/') . '/file'); + $this->addProvider('template', new Template($modx, $pdoTools)); + $this->addProvider('file', new File($modx, $pdoTools)); + + $default_options = [ + 'disable_cache' => !$pdoTools->config('useFenomCache'), + 'force_compile' => !$pdoTools->config('useFenomCache'), + 'force_include' => !$pdoTools->config('useFenomCache'), + 'auto_reload' => $pdoTools->config('useFenomCache'), + ]; + if ($options = json_decode($modx->getOption('pdotools_fenom_options'), true)) { $options = array_merge($default_options, $options); } else { $options = $default_options; } - if (!$pdoTools->config['useFenomPHP']) { + if (!$pdoTools->config('useFenomPHP')) { $this->removeAccessor('php'); $options['disable_native_funcs'] = true; } $this->setOptions($options); - $this->pdoTools = $pdoTools; - $this->modx = $pdoTools->modx; - $this->_addDefaultModifiers(); $this->modx->invokeEvent( 'pdoToolsOnFenomInit', - array( + [ 'fenom' => $this, - 'config' => $pdoTools->config, - ) + 'config' => $pdoTools->config(), + ] ); } + /** + * Parse content with Fenom syntax + * + * @param $chunk + * @param array $properties + * @return string + */ + public function process($chunk, array $properties = []) + { + $content = is_array($chunk) + ? trim($chunk['content']) + : trim($chunk); + if (empty($this->pdoTools->config('useFenom')) || !preg_match($this->pdoTools->config('fenomSyntax'), $content)) { + return $content; + } + + $name = ''; + if (is_array($chunk)) { + if (!empty($chunk['binding'])) { + $name = $chunk['binding'] . '/'; + } + if (!empty($chunk['id'])) { + $name .= $chunk['id']; + } elseif (!empty($chunk['name'])) { + $name .= $chunk['name']; + } else { + $name .= md5($content); + } + } else { + $name = md5($content); + } + /** @var \Fenom\Template $tpl */ + if (!$tpl = $this->pdoTools->getStore($name, 'fenom')) { + if (!empty($this->pdoTools->config('useFenomCache'))) { + $cache_options = [ + 'cache_key' => 'pdotools/' . $name, + ]; + if (!$cache = $this->pdoTools->getCache($cache_options)) { + if ($tpl = $this->_compileChunk($content, $name)) { + $this->pdoTools->setCache($tpl->getTemplateCode(), $cache_options); + } + } else { + $cache = preg_replace('#^<\?php#', '', $cache); + $tpl = eval($cache); + } + } else { + $tpl = $this->_compileChunk($content, $name); + } + if ($tpl) { + $this->pdoTools->setStore($name, $tpl, 'fenom'); + } + } + + if ($tpl instanceof Render) { + $properties['_modx'] = new App($this->modx, $this->pdoTools); + $properties['_pls'] = $properties; + + // Add system objects + if (!empty($this->pdoTools->config('useFenomMODX'))) { + $properties['modx'] = $this->modx; + $properties['pdoTools'] = $this; + } + try { + $content = $tpl->fetch($properties); + } catch (Exception $e) { + $this->modx->log(modX::LOG_LEVEL_ERROR, $e->getMessage()); + $this->modx->log(modX::LOG_LEVEL_INFO, $tpl->getTemplateCode()); + } + } + + return $content; + } /** * Set compile directory * * @param string $dir directory to store compiled templates in * + * @return \Fenom * @throws LogicException - * @return Fenom */ public function setCompileDir($dir) { $dir = str_replace(MODX_CORE_PATH, '', $dir); $path = MODX_CORE_PATH; $tmp = explode('/', trim($dir, '/')); + // FIX: use Flysystem foreach ($tmp as $v) { if (!empty($v)) { $path .= $v . '/'; } - if (!file_exists($path)) { - mkdir($path); + if (!file_exists($path) && !mkdir($path) && !is_dir($path)) { + $this->modx->log(xPDO::LOG_LEVEL_ERROR, sprintf('Directory "%s" was not created', $path)); } } return parent::setCompileDir($path); } + /** + * Compiles Fenom chunk + * + * @param $content + * @param string $name + * + * @return \Fenom\Template + */ + protected function _compileChunk($content, $name = '') + { + if (empty($name)) { + $name = md5($content); + } + try { + $tpl = $this->getRawTemplate()->source($name, $content, true); + $this->pdoTools->addTime('Compiled Fenom chunk with name "' . $name . '"'); + } catch (Exception $e) { + $this->modx->log(modX::LOG_LEVEL_ERROR, $e->getMessage()); + $this->modx->log(modX::LOG_LEVEL_INFO, $content); + if ($this->modx->getOption('pdotools_fenom_save_on_errors')) { + $this->pdoTools->setCache($content, ['cache_key' => 'error/' . $name]); + } + $tpl = $this->getRawTemplate()->source($name, '', false); + $this->pdoTools->addTime('Can`t compile Fenom chunk with name "' . $name . '": ' . $e->getMessage()); + } + + return $tpl; + } + /** * Add default modifiers @@ -99,26 +207,20 @@ protected function _addDefaultModifiers() $modx = $this->modx; $pdo = $this->pdoTools; $fenom = $this; - if (!$micro = $pdo->getStore('microMODX')) { - if (!class_exists('microMODX')) { - require '_micromodx.php'; - } - $micro = new microMODX($pdo); - $pdo->setStore('microMODX', $micro); - } + $micro = new App($modx, $pdo); // PHP Functions $this->_allowed_funcs = array_merge( $this->_allowed_funcs, - array( + [ 'rand' => 1, 'number_format' => 1, - ) + ] ); $this->_modifiers = array_merge( $this->_modifiers, - array( + [ 'md5' => 'md5', 'sha1' => 'sha1', 'crc32' => 'crc32', @@ -140,7 +242,7 @@ protected function _addDefaultModifiers() 'number' => 'number_format', 'reset' => 'reset', 'end' => 'end', - ) + ] ); // String Modifiers @@ -196,8 +298,8 @@ protected function _addDefaultModifiers() $string = preg_replace('/&(#[0-9]+|[a-z]+);/i', '&$1;', htmlspecialchars($string)); return str_replace( - array('[', ']', '`', '{', '}'), - array('[', ']', '`', '{', '}'), + ['[', ']', '`', '{', '}'], + ['[', ']', '`', '{', '}'], $string ); }; @@ -210,7 +312,7 @@ protected function _addDefaultModifiers() }; $this->_modifiers['stripmodxtags'] = function ($string) { - return preg_replace("/\\[\\[([^\\[\\]]++|(?R))*?\\]\\]/s", '', $string); + return preg_replace("/\\[\\[([^\\[\\]]++|(?R))*?]]/s", '', $string); }; $this->_modifiers['cdata'] = function ($string, $enc = 'utf-8') { @@ -241,7 +343,7 @@ protected function _addDefaultModifiers() if (is_array($string)) { $string = array_reverse($string); } else { - $ar = array(); + $ar = []; preg_match_all('/(\d+)?./us', $string, $ar); $string = join('', array_reverse($ar[0])); } @@ -269,17 +371,17 @@ protected function _addDefaultModifiers() $output = '—'; if (!empty($date)) { - if (empty($modx->lexicon)) { - $modx->getService('lexicon', 'modLexicon'); + /** @var modLexicon $lexicon */ + if ($lexicon = $modx->services->get('lexicon')) { + $lexicon->load('filters'); } - $modx->lexicon->load('filters'); $time = !is_numeric($date) ? strtotime($date) : $date; if ($time >= strtotime('today')) { - $output = $modx->lexicon('today_at', array('time' => strftime('%I:%M %p', $time))); + $output = $modx->lexicon('today_at', ['time' => strftime('%I:%M %p', $time)]); } elseif ($time >= strtotime('yesterday')) { - $output = $modx->lexicon('yesterday_at', array('time' => strftime('%I:%M %p', $time))); + $output = $modx->lexicon('yesterday_at', ['time' => strftime('%I:%M %p', $time)]); } else { $output = strftime($format, $time); } @@ -292,7 +394,7 @@ protected function _addDefaultModifiers() $this->_modifiers['ismember'] = $this->_modifiers['memberof'] = - $this->_modifiers['mo'] = function ($id, $groups = array(), $matchAll = false) use ($modx, $pdo) { + $this->_modifiers['mo'] = function ($id, $groups = [], $matchAll = false) use ($modx, $pdo) { $pdo->debugParserModifier($id, 'ismember', $groups); if (is_string($groups)) { $groups = array_map('trim', explode(',', $groups)); @@ -303,7 +405,7 @@ protected function _addDefaultModifiers() $id = $modx->user->get('id'); $user = $modx->user; } else { - $user = $modx->getObject('modUser', ['id' => intval($id)]); + $user = $modx->getObject(modUser::class, ['id' => (int)$id]); } $member = is_object($user) ? $user->isMember($groups, $matchAll) : false; $pdo->debugParserModifier($id, 'ismember', $groups); @@ -340,7 +442,7 @@ protected function _addDefaultModifiers() $modulusOneHundred = $amount % 100; switch ($amount % 10) { case 1: - $text = $modulusOneHundred == 11 + $text = $modulusOneHundred === 11 ? $variants[2] : $variants[0]; break; @@ -362,7 +464,7 @@ protected function _addDefaultModifiers() // MODX Functions - $this->_modifiers['url'] = function ($id, $options = array(), $args = array()) use ($pdo) { + $this->_modifiers['url'] = function ($id, $options = [], $args = []) use ($pdo) { $properties = array_merge($options, $args); $pdo->debugParserModifier($id, 'url', $properties); $url = $pdo->makeUrl($id, $options, $args); @@ -371,7 +473,7 @@ protected function _addDefaultModifiers() return $url; }; - $this->_modifiers['lexicon'] = function ($key, $params = array(), $language = '') use ($modx) { + $this->_modifiers['lexicon'] = function ($key, $params = [], $language = '') use ($modx) { return $modx->lexicon($key, $params, $language); }; @@ -383,7 +485,7 @@ protected function _addDefaultModifiers() } $output = ''; /** @var modUser $user */ - if ($user = $modx->getObjectGraph('modUser', '{"Profile":{}}', $id)) { + if ($user = $modx->getObjectGraph(modUser::class, '{"Profile":{}}', $id)) { $data = array_merge($user->toArray(), $user->Profile->toArray()); unset($data['cachepwd'], $data['salt'], $data['sessionid'], $data['password'], $data['session_stale'], $data['remote_key'], $data['remote_data'], $data['hash_class']); @@ -409,14 +511,14 @@ protected function _addDefaultModifiers() $field = $id; $resource = $modx->resource; } elseif (!$resource = $pdo->getStore($id, 'resource')) { - $resource = $modx->getObject('modResource', ['id' => intval($id)]); + $resource = $modx->getObject(modResource::class, ['id' => (int)$id]); $pdo->setStore($id, $resource, 'resource'); } $output = ''; if (!empty($resource)) { if (!empty($field)) { - if (strtolower($field) == 'content') { + if (strtolower($field) === 'content') { $output = $resource->getContent(); } else { $output = $resource->get($field); @@ -433,7 +535,7 @@ protected function _addDefaultModifiers() return $output; }; - $this->_modifiers['snippet'] = function ($name, $params = array()) use ($pdo) { + $this->_modifiers['snippet'] = function ($name, $params = []) use ($pdo) { $pdo->debugParserModifier($name, 'snippet', $params); $result = $pdo->runSnippet($name, $params); $pdo->debugParserModifier($name, 'snippet', $params); @@ -441,7 +543,7 @@ protected function _addDefaultModifiers() return $result; }; - $this->_modifiers['chunk'] = function ($name, $params = array()) use ($pdo) { + $this->_modifiers['chunk'] = function ($name, $params = []) use ($pdo) { $pdo->debugParserModifier($name, 'chunk', $params); $result = $pdo->getChunk($name, $params); $pdo->debugParserModifier($name, 'chunk', $params); @@ -505,11 +607,6 @@ protected function _addDefaultModifiers() : json_decode($string, $assoc, $depth, $options); }; - $this->_modifiers['setOption'] = function ($var, $key) use ($modx) { - $this->modx->log(modX::LOG_LEVEL_ERROR, '[pdoTools] The setOption modifier is deprecated and will be removed in the next version.'); - $modx->setOption($key, $var); - }; - $this->_modifiers['getOption'] = $this->_modifiers['option'] = $this->_modifiers['config'] = function ($key) use ($modx) { @@ -524,56 +621,29 @@ protected function _addDefaultModifiers() return preg_quote($value, $delimiter); }; - $this->_modifiers['preg_match'] = function ($value, $pattern) use ($fenom) { - if (PHP_VERSION_ID < 50400) { - $method = new ReflectionMethod($fenom, '_assertNoEval'); - $method->setAccessible(true); - $method->invoke($fenom, $pattern); - } else { - $fenom->_assertNoEval($pattern); - } - + $this->_modifiers['preg_match'] = function ($value, $pattern) { return preg_match($pattern, $value); }; - $this->_modifiers['preg_get'] = function ($value, $pattern, $group = 0) use ($fenom) { - if (PHP_VERSION_ID < 50400) { - $method = new ReflectionMethod($fenom, '_assertNoEval'); - $method->setAccessible(true); - $method->invoke($fenom, $pattern); - } else { - $fenom->_assertNoEval($pattern); - } + $this->_modifiers['preg_get'] = function ($value, $pattern, $group = 0) { if (!preg_match($pattern, $value, $matches)) { return null; } - return isset($matches[$group]) - ? $matches[$group] - : null; + return $matches[$group] ?? null; }; - $this->_modifiers['preg_get_all'] = function ($value, $pattern, $group = 0) use ($fenom) { - if (PHP_VERSION_ID < 50400) { - $method = new ReflectionMethod($fenom, '_assertNoEval'); - $method->setAccessible(true); - $method->invoke($fenom, $pattern); - } else { - $fenom->_assertNoEval($pattern); - } + $this->_modifiers['preg_get_all'] = function ($value, $pattern, $group = 0) { if (!preg_match_all($pattern, $value, $matches, PREG_PATTERN_ORDER)) { - return array(); + return []; } - return isset($matches[$group]) - ? $matches[$group] - : array(); + return $matches[$group] ?? []; }; - $this->_modifiers['preg_grep'] = function ($value, $pattern, $flags = '') use ($fenom) { - $fenom->_assertNoEval($pattern); + $this->_modifiers['preg_grep'] = function ($value, $pattern, $flags = '') { if (is_string($flags)) { - $flags = $flags == 'invert' + $flags = $flags === 'invert' ? PREG_GREP_INVERT : 0; } @@ -582,83 +652,39 @@ protected function _addDefaultModifiers() }; $this->_modifiers['preg_replace'] = function ($value, $pattern, $replacement = '', $limit = -1) use ($fenom) { - if (PHP_VERSION_ID < 50400) { - $method = new ReflectionMethod($fenom, '_assertNoEval'); - $method->setAccessible(true); - $method->invoke($fenom, $pattern); - } else { - $fenom->_assertNoEval($pattern); - } - return preg_replace($pattern, $replacement, $value, $limit); }; $this->_modifiers['preg_filter'] = function ($value, $pattern, $replacement = '', $limit = -1) use ($fenom) { - if (PHP_VERSION_ID < 50400) { - $method = new ReflectionMethod($fenom, '_assertNoEval'); - $method->setAccessible(true); - $method->invoke($fenom, $pattern); - } else { - $fenom->_assertNoEval($pattern); - } - return preg_filter($pattern, $replacement, $value, $limit); }; $this->_modifiers['preg_split'] = function ($value, $pattern) use ($fenom) { - if (PHP_VERSION_ID < 50400) { - $method = new ReflectionMethod($fenom, '_assertNoEval'); - $method->setAccessible(true); - $method->invoke($fenom, $pattern); - } else { - $fenom->_assertNoEval($pattern); - } - return preg_split($pattern, $value); }; } - /** - * Check that the regex doesn't use the eval modifier - * - * @param $pattern - * - * @throws Exception - */ - protected function _assertNoEval($pattern) - { - if (is_array($pattern)) { - foreach ($pattern as $item) { - $this->_assertNoEval($item); - } - } elseif (preg_match('/(.).*\1(.+)$/', trim($pattern), $match) && strpos($match[2], 'e') !== false) { - throw new LogicException("Using the eval modifier for regular expressions is not allowed: \"$pattern\""); - } - } - - /** * Modifier autoloader * * @param string $name * @param \Fenom\Template $template * - * @return Closure + * @return callable */ protected function _loadModifier($name, $template) { - $modx = $this->modx; $pdo = $this->pdoTools; - return function ($input, $options = null) use ($name, $modx, $pdo) { + return function ($input, $options = null) use ($name, $pdo) { $pdo->debugParserModifier($input, $name, $options); - $result = $pdo->runSnippet($name, array( + $result = $pdo->runSnippet($name, [ 'input' => $input, 'options' => $options, 'pdoTools' => $pdo, - )); + ]); $pdo->debugParserModifier($input, $name, $options); return $result === false @@ -666,5 +692,4 @@ protected function _loadModifier($name, $template) : $result; }; } - } diff --git a/core/components/pdotools/model/fenom/Providers/ModChunk.php b/core/components/pdotools/src/Parsing/Fenom/Providers/Chunk.php similarity index 64% rename from core/components/pdotools/model/fenom/Providers/ModChunk.php rename to core/components/pdotools/src/Parsing/Fenom/Providers/Chunk.php index ac07d19f..264e6e09 100644 --- a/core/components/pdotools/model/fenom/Providers/ModChunk.php +++ b/core/components/pdotools/src/Parsing/Fenom/Providers/Chunk.php @@ -1,17 +1,26 @@ modx = $modx; $this->pdoTools = $pdoTools; - $this->modx = $pdoTools->modx; } @@ -24,9 +33,9 @@ public function templateExists($tpl) { $c = is_numeric($tpl) && $tpl > 0 ? $tpl - : array('name' => $tpl); + : ['name' => $tpl]; - return (bool)$this->modx->getCount('modChunk', $c); + return (bool)$this->modx->getCount(modChunk::class, $c); } @@ -44,13 +53,13 @@ public function getSource($tpl, &$time) $tpl = substr($tpl, 0, $pos); } $c = is_numeric($tpl) && $tpl > 0 - ? $tpl - : array('name' => $tpl); - /** @var modChunk $chunk */ - if ($element = $this->modx->getObject('modChunk', $c)) { + ? ['id' => $tpl] + : ['name' => $tpl]; + /** @var modChunk $element */ + if ($element = $this->modx->getObject(modChunk::class, $c)) { $content = $element->getContent(); - $properties = array(); + $properties = []; if (!empty($propertySet)) { if ($tmp = $element->getPropertySet($propertySet)) { $properties = $tmp; @@ -59,11 +68,11 @@ public function getSource($tpl, &$time) $properties = $element->getProperties(); } if (!empty($content) && !empty($properties)) { - $useFenom = $this->pdoTools->config['useFenom']; - $this->pdoTools->config['useFenom'] = false; + $useFenom = $this->pdoTools->config('useFenom'); + $this->pdoTools->config(['useFenom' => false]); $content = $this->pdoTools->parseChunk('@INLINE ' . $content, $properties); - $this->pdoTools->config['useFenom'] = $useFenom; + $this->pdoTools->config(['useFenom' => $useFenom]); } } @@ -80,12 +89,11 @@ public function getLastModified($tpl) { $c = is_numeric($tpl) && $tpl > 0 ? $tpl - : array('name' => $tpl); + : ['name' => $tpl]; + /** @var modChunk $chunk */ - if ($chunk = $this->modx->getObject('modChunk', $c)) { - if ($chunk->isStatic() && $file = $chunk->getSourceFile()) { - return filemtime($file); - } + if (($chunk = $this->modx->getObject(modChunk::class, $c)) && $chunk->isStatic() && $file = $chunk->getSourceFile()) { + return filemtime($file); } return time(); @@ -107,17 +115,17 @@ public function verify(array $templates) /** * Get all names of template from provider - * @return array|\Iterator + * @return array */ public function getList() { - $c = $this->modx->newQuery('modChunk'); + $c = $this->modx->newQuery(modChunk::class); $c->select('name'); if ($c->prepare() && $c->stmt->execute()) { return $c->stmt->fetchAll(PDO::FETCH_COLUMN); } - return array(); + return []; } -} \ No newline at end of file +} diff --git a/core/components/pdotools/src/Parsing/Fenom/Providers/File.php b/core/components/pdotools/src/Parsing/Fenom/Providers/File.php new file mode 100644 index 00000000..92768ae8 --- /dev/null +++ b/core/components/pdotools/src/Parsing/Fenom/Providers/File.php @@ -0,0 +1,27 @@ +config('elementsPath')) + ? MODX_CORE_PATH . 'cache/' + : $pdoTools->config('elementsPath'); + + parent::__construct($dir); + + $this->modx = $modx; + $this->pdoTools = $pdoTools; + } +} \ No newline at end of file diff --git a/core/components/pdotools/model/fenom/Providers/ModTemplate.php b/core/components/pdotools/src/Parsing/Fenom/Providers/Template.php similarity index 67% rename from core/components/pdotools/model/fenom/Providers/ModTemplate.php rename to core/components/pdotools/src/Parsing/Fenom/Providers/Template.php index 2ded26da..38e818ce 100644 --- a/core/components/pdotools/model/fenom/Providers/ModTemplate.php +++ b/core/components/pdotools/src/Parsing/Fenom/Providers/Template.php @@ -1,17 +1,27 @@ modx = $modx; $this->pdoTools = $pdoTools; - $this->modx = $pdoTools->modx; } @@ -24,9 +34,9 @@ public function templateExists($tpl) { $c = is_numeric($tpl) && $tpl > 0 ? $tpl - : array('templatename' => $tpl); + : ['templatename' => $tpl]; - return (bool)$this->modx->getCount('modTemplate', $c); + return (bool)$this->modx->getCount(modTemplate::class, $c); } @@ -45,12 +55,12 @@ public function getSource($tpl, &$time) } $c = is_numeric($tpl) && $tpl > 0 ? $tpl - : array('templatename' => $tpl); + : ['templatename' => $tpl]; /** @var modChunk $chunk */ - if ($element = $this->modx->getObject('modTemplate', $c)) { + if ($element = $this->modx->getObject(modTemplate::class, $c)) { $content = $element->getContent(); - $properties = array(); + $properties = []; if (!empty($propertySet)) { if ($tmp = $element->getPropertySet($propertySet)) { $properties = $tmp; @@ -59,11 +69,11 @@ public function getSource($tpl, &$time) $properties = $element->getProperties(); } if (!empty($content) && !empty($properties)) { - $useFenom = $this->pdoTools->config['useFenom']; - $this->pdoTools->config['useFenom'] = false; + $useFenom = $this->pdoTools->getConfig('useFenom'); + $this->pdoTools->config(['useFenom' => false]); $content = $this->pdoTools->parseChunk('@INLINE ' . $content, $properties); - $this->pdoTools->config['useFenom'] = $useFenom; + $this->pdoTools->config(['useFenom' => $useFenom]); } } @@ -80,9 +90,9 @@ public function getLastModified($tpl) { $c = is_numeric($tpl) && $tpl > 0 ? $tpl - : array('templatename' => $tpl); + : ['templatename' => $tpl]; /** @var modChunk $chunk */ - if ($chunk = $this->modx->getObject('modTemplate', $c)) { + if ($chunk = $this->modx->getObject(modTemplate::class, $c)) { if ($chunk->isStatic() && $file = $chunk->getSourceFile()) { return filemtime($file); } @@ -107,17 +117,17 @@ public function verify(array $templates) /** * Get all names of template from provider - * @return array|\Iterator + * @return array|Iterator */ public function getList() { - $c = $this->modx->newQuery('modTemplate'); + $c = $this->modx->newQuery(modTemplate::class); $c->select('templatename'); if ($c->prepare() && $c->stmt->execute()) { return $c->stmt->fetchAll(PDO::FETCH_COLUMN); } - return array(); + return []; } } \ No newline at end of file diff --git a/core/components/pdotools/model/pdotools/_micromodx.php b/core/components/pdotools/src/Parsing/Fenom/Support/App.php similarity index 73% rename from core/components/pdotools/model/pdotools/_micromodx.php rename to core/components/pdotools/src/Parsing/Fenom/Support/App.php index 321f9fab..ba4ddf6e 100644 --- a/core/components/pdotools/model/pdotools/_micromodx.php +++ b/core/components/pdotools/src/Parsing/Fenom/Support/App.php @@ -1,75 +1,43 @@ modx = $modx = $pdoTools->modx; + $this->modx = $modx; $this->pdoTools = $pdoTools; $this->config = $modx->config; - $this->lexicon = new microMODXLexicon($modx); - $this->cacheManager = new microMODXCacheManager($modx); - } - - /** - * @param $name - * @return array|null - */ - public function __get($name) - { - $data = null; - if ($name == 'resource' && $this->modx->resource) { - if (!$data = $this->getStore('resource', 'fenom')) { - $data = $this->modx->resource->toArray(); - $data['content'] = $this->modx->resource->getContent(); - // TV parameters - foreach ($data as $k => $v) { - if (is_array($v) && !empty($v[0]) && $k == $v[0]) { - $data[$k] = $this->modx->resource->getTVValue($k); - } elseif ($k[0] == '_') { - unset($data[$k]); - } - } - $this->setStore('resource', $data, 'fenom'); - } - } elseif ($name == 'user' && $this->modx->user) { - if (!$data = $this->getStore('user', 'fenom')) { - $data = $this->modx->user->toArray(); - /** @var modUserProfile $profile */ - if ($profile = $this->modx->user->Profile) { - $tmp = $profile->toArray(); - unset($tmp['id']); - $data = array_merge($data, $tmp); - } - $this->setStore('user', $data, 'fenom'); - } - } elseif ($name == 'context' && $this->modx->context) { - if (!$data = $this->getStore('context', 'fenom')) { - $data = $this->modx->context->toArray(); - $this->setStore('context', $data, 'fenom'); - } - } - - return $data; + $this->lexicon = new Lexicon($modx); + $this->cacheManager = new CacheManager($modx); } @@ -80,7 +48,7 @@ public function __get($name) * * @return null|string */ - public function lexicon($key, $params = [], $language = '') + public function lexicon($key, array $params = [], $language = '') { return $this->modx->lexicon($key, $params, $language); } @@ -104,13 +72,13 @@ public function getChunk($name, array $placeholders = []) /** * @param $name - * @param $placeholders + * @param array $placeholders * @param string $prefix * @param string $suffix * * @return string */ - public function parseChunk($name, $placeholders, $prefix = '[[+', $suffix = ']]') + public function parseChunk($name, array $placeholders, $prefix = '[[+', $suffix = ']]') { $this->pdoTools->debugParserMethod('parseChunk', $name, $placeholders); $result = $this->pdoTools->parseChunk($name, $placeholders, $prefix, $suffix); @@ -147,9 +115,10 @@ public function runSnippet($name, array $params = []) */ public function makeUrl($id, $context = '', $args = '', $scheme = -1, array $options = []) { - $this->pdoTools->debugParserMethod('makeUrl', $id, $args); + $properties = [$args, $scheme, $options]; + $this->pdoTools->debugParserMethod('makeUrl', $id, $properties); $result = $this->modx->makeUrl($id, $context, $args, $scheme, $options); - $this->pdoTools->debugParserMethod('makeUrl', $id, $args); + $this->pdoTools->debugParserMethod('makeUrl', $id, $properties); return $result; } @@ -236,7 +205,7 @@ public function regClientHTMLBlock($html) public function runProcessor($action = '', $scriptProperties = [], $options = []) { $this->pdoTools->debugParserMethod('runProcessor', $action, $scriptProperties); - /** @var modProcessorResponse $response */ + /** @var ProcessorResponse $response */ $response = $this->modx->runProcessor($action, $scriptProperties, $options); $this->pdoTools->debugParserMethod('runProcessor', $action, $scriptProperties); @@ -465,7 +434,7 @@ public function getInfo($key = '', $string = true, $tpl = '@INLINE {$key}: {$val $queryTime = sprintf("%2.4f s", $this->modx->queryTime); $totalTime = sprintf("%2.4f s", $totalTime); $phpTime = sprintf("%2.4f s", $totalTime - $queryTime); - $queries = isset($this->modx->executedQueries) ? $this->modx->executedQueries : 0; + $queries = $this->modx->executedQueries ?? 0; $source = $this->modx->resourceGenerated ? 'database' : 'cache'; $info = [ @@ -479,19 +448,17 @@ public function getInfo($key = '', $string = true, $tpl = '@INLINE {$key}: {$val if (empty($key) && !empty($string)) { $output = []; - foreach ($info as $key => $value) { + foreach ($info as $k => $value) { $output[] = $this->pdoTools->parseChunk($tpl, [ - 'key' => $key, + 'key' => $k, 'value' => $value, ]); } return implode("\n", $output); - } else { - return !empty($key) && isset($info[$key]) - ? $info[$key] - : $info; } + + return !empty($key) && isset($info[$key]) ? $info[$key] : $info; } @@ -512,9 +479,10 @@ public function getResource($id, array $options = []) } $output = false; $this->pdoTools->debugParserMethod('getResource', $where, $options); - /** @var pdoFetch $pdoFetch */ - if ($pdoFetch = $this->modx->getService('pdoFetch')) { - $output = $pdoFetch->getArray('modResource', $where, $options); + /** @var Fetch $pdoFetch */ + if ($this->modx->services->has('pdofetch')) { + $pdoFetch = $this->modx->services->get('pdofetch'); + $output = $pdoFetch->getArray(modResource::class, $where, $options); } $this->pdoTools->debugParserMethod('getResource', $where, $options); @@ -532,9 +500,10 @@ public function getResources($where, array $options = []) { $output = false; $this->pdoTools->debugParserMethod('getResources', $where, $options); - /** @var pdoFetch $pdoFetch */ - if ($pdoFetch = $this->modx->getService('pdoFetch')) { - $output = $pdoFetch->getCollection('modResource', $where, $options); + /** @var Fetch $pdoFetch */ + if ($this->modx->services->has('pdofetch')) { + $pdoFetch = $this->modx->services->get('pdofetch'); + $output = $pdoFetch->getCollection(modResource::class, $where, $options); } $this->pdoTools->debugParserMethod('getResources', $where, $options); @@ -552,89 +521,45 @@ public function cleanAlias($alias = '') return modResource::filterPathSegment($this->modx, $alias); } -} - - -/** - * Class microMODXLexicon - */ -class microMODXLexicon -{ - /** @var modX $modx */ - protected $modx; - /** @var modLexicon $lexicon */ - protected $lexicon; - - /** - * @param modX $modx - */ - function __construct(modX $modx) - { - $this->modx = &$modx; - $this->lexicon = $this->modx->getService('lexicon', 'modLexicon'); - } - - - /** - * + * @param $name + * @return array|null */ - public function load() + public function __get($name) { - $topics = func_get_args(); - - foreach ($topics as $topic) { - $this->lexicon->load($topic); + $data = null; + if ($name === 'resource' && $this->modx->resource) { + if (empty($this->resource)) { + $this->resource = $this->modx->resource->toArray(); + $this->resource['content'] = $this->modx->resource->getContent(); + // TV parameters + foreach ($this->resource as $k => $v) { + if (is_array($v) && !empty($v[0]) && $k == $v[0]) { + $this->resource[$k] = $this->modx->resource->getTVValue($k); + } elseif ($k[0] === '_') { + unset($this->resource[$k]); + } + } + } + } elseif ($name === 'user' && $this->modx->user) { + if (empty($this->user)) { + $this->user = $this->modx->user->toArray(); + if ($profile = $this->modx->user->getOne('Profile')) { + $tmp = $profile->toArray(); + unset($tmp['id']); + $this->user = array_merge($this->user, $tmp); + } + $this->user = array_diff_key( + $this->user, + ['sessionid' => 1, 'password' => 1, 'cachepwd' => 1, 'salt' => 1, 'session_stale' => 1, 'remote_key' => 1, 'remote_data' => 1, 'hash_class' => 1] + ); + } + } elseif ($name === 'context' && $this->modx->context) { + if (empty($this->context)) { + $this->context = $this->modx->context->toArray(); + } } - } - -} - - -/** - * Class microMODXCacheManager - */ -class microMODXCacheManager -{ - /** @var modX $modx */ - protected $modx; - /** @var modCacheManager $cacheManager */ - protected $cacheManager; - - - /** - * @param modX $modx - */ - function __construct(modX $modx) - { - $this->modx = &$modx; - $this->cacheManager = $modx->getCacheManager(); - } - - /** - * @param $key - * @param array $options - * - * @return mixed - */ - public function get($key, $options = []) - { - return $this->cacheManager->get($key, $options); + return $this->{$name}; } - - - /** - * @param $key - * @param $var - * @param int $lifetime - * - * @return bool - */ - public function set($key, &$var, $lifetime = 0) - { - // $options is not used due to security reasons - return $this->cacheManager->set($key, $var, $lifetime); - } - } diff --git a/core/components/pdotools/src/Parsing/Fenom/Support/CacheManager.php b/core/components/pdotools/src/Parsing/Fenom/Support/CacheManager.php new file mode 100644 index 00000000..3039f1ce --- /dev/null +++ b/core/components/pdotools/src/Parsing/Fenom/Support/CacheManager.php @@ -0,0 +1,51 @@ +modx = $modx; + $this->cacheManager = $modx->getCacheManager(); + } + + + /** + * @param string $key + * @param array $options + * + * @return mixed + */ + public function get($key, $options = []) + { + return $this->cacheManager->get($key, $options); + } + + + /** + * @param string $key + * @param mixed $var + * @param int $lifetime + * + * @return bool + */ + public function set($key, &$var, $lifetime = 0) + { + // $options is not used due to security reasons + return $this->cacheManager->set($key, $var, $lifetime); + } + +} diff --git a/core/components/pdotools/src/Parsing/Fenom/Support/Lexicon.php b/core/components/pdotools/src/Parsing/Fenom/Support/Lexicon.php new file mode 100644 index 00000000..48598b8e --- /dev/null +++ b/core/components/pdotools/src/Parsing/Fenom/Support/Lexicon.php @@ -0,0 +1,38 @@ +modx = $modx; + $this->lexicon = $this->modx->services->get('lexicon'); + } + + + /** + * + */ + public function load() + { + $topics = func_get_args(); + + foreach ($topics as $topic) { + $this->lexicon->load($topic); + } + } + +} diff --git a/core/components/pdotools/model/pdotools/pdoparser.class.php b/core/components/pdotools/src/Parsing/Parser.php similarity index 74% rename from core/components/pdotools/model/pdotools/pdoparser.class.php rename to core/components/pdotools/src/Parsing/Parser.php index dd12b436..e4422afc 100644 --- a/core/components/pdotools/model/pdotools/pdoparser.class.php +++ b/core/components/pdotools/src/Parsing/Parser.php @@ -1,28 +1,34 @@ getOption('pdoTools.class', null, 'pdotools.pdotools', true); - $path = $modx->getOption('pdotools_class_path', null, MODX_CORE_PATH . 'components/pdotools/model/', true); - if ($pdoClass = $modx->loadClass($fqn, $path, false, true)) { - $this->pdoTools = new $pdoClass($modx); - } + $this->modx = $modx; + $this->pdoTools = $pdoTools; } @@ -50,15 +56,18 @@ public function processElementTags( $tokens = array(), $depth = 0 ) { - if (is_string($content) && $processUncacheable && !empty($this->pdoTools->config['useFenomParser'])) { - if (preg_match_all('#\{ignore\}(.*?)\{\/ignore\}#is', $content, $ignores)) { + if (is_string($content) && $processUncacheable && !empty($this->pdoTools->config('useFenomParser'))) { + if (preg_match_all('#{ignore}(.*?){/ignore}#is', $content, $ignores)) { foreach ($ignores[1] as $ignore) { $key = 'ignore_' . md5($ignore); - $this->pdoTools->ignores[$key] = $ignore; + $this->ignores[$key] = $ignore; $content = str_replace($ignore, $key, $content); } } - $content = $this->pdoTools->fenom($content, $this->modx->placeholders); + $_processingUncacheable = $this->_processingUncacheable; + $this->_processingUncacheable = true; + $content = $this->pdoTools->getFenom()->process($content, $this->modx->placeholders); + $this->_processingUncacheable = $_processingUncacheable; } return parent::processElementTags($parentTag, $content, $processUncacheable, $removeUnprocessed, $prefix, @@ -66,7 +75,6 @@ public function processElementTags( ); } - /** * Quickly processes a simple tag and returns the result. * @@ -153,15 +161,15 @@ public function processTag($tag, $processUncacheable = true) if (is_numeric($tmp[0])) { /** @var modResource $resource */ if (!$resource = $this->pdoTools->getStore($tmp[0], 'resource')) { - $resource = $this->modx->getObject('modResource', $tmp[0]); + $resource = $this->modx->getObject('modResource', ['id' => $tmp[0]]); $this->pdoTools->setStore($tmp[0], $resource, 'resource'); } $output = ''; - if (!empty($resource)) { + if ($resource !== null) { // Field specified if (!empty($tmp[1])) { $tmp[1] = strtolower($tmp[1]); - if ($tmp[1] == 'content') { + if ($tmp[1] === 'content') { $output = $resource->getContent(); } // Resource field elseif ($field = $resource->get($tmp[1])) { @@ -170,7 +178,7 @@ public function processTag($tag, $processUncacheable = true) $count = count($tmp2); foreach ($tmp2 as $k => $v) { if (isset($field[$v])) { - if ($k == ($count - 1)) { + if ($k === ($count - 1)) { $output = $field[$v]; } else { $field = $field[$v]; @@ -221,19 +229,15 @@ public function processTag($tag, $processUncacheable = true) } // Field specified if (!empty($tmp[1])) { - $field = isset($array[$tmp[1]]) - ? $array[$tmp[1]] - : ''; + $field = $array[$tmp[1]] ?? ''; $output = $field; - if (is_array($field)) { - if ($length > 2) { - foreach ($tmp as $k => $v) { - if ($k === 0) { - continue; - } - if (isset($field[$v])) { - $output = $field[$v]; - } + if (is_array($field) && $length > 2) { + foreach ($tmp as $k => $v) { + if ($k === 0) { + continue; + } + if (isset($field[$v])) { + $output = $field[$v]; } } } @@ -251,15 +255,14 @@ public function processTag($tag, $processUncacheable = true) // Processing output filters if ($processed) { if (strpos($outerTag, ':') !== false) { - /** @var pdoTag $object */ - $tag = new pdoTag($this->modx); - $tag->_content = $output; - $tag->setTag($outerTag); - $tag->setToken($token); - $tag->setContent(ltrim(rtrim($outerTag, ']'), '[!' . $token)); - $tag->setCacheable(!$processUncacheable); - $tag->process(); - $output = $tag->_output; + $tagObj = new Tag($this->modx); + $tagObj->_content = $output; + $tagObj->setTag($outerTag); + $tagObj->setToken($token); + $tagObj->setContent(ltrim(rtrim($outerTag, ']'), '[!' . $token)); + $tagObj->setCacheable(!$processUncacheable); + $tagObj->process(); + $output = $tagObj->_output; } if ($this->modx->getDebug() === true) { $this->modx->log(xPDO::LOG_LEVEL_DEBUG, @@ -277,45 +280,3 @@ public function processTag($tag, $processUncacheable = true) } } - - -class pdoTag extends modTag -{ - /** - * @param null $properties - * @param null $content - * - * @return bool - */ - public function process($properties = null, $content = null) - { - $this->filterInput(); - - if ($this->modx->getDebug() === true) { - $this->modx->log( - xPDO::LOG_LEVEL_DEBUG, "Processing Element: " . $this->get('name') . - ($this->_tag ? "\nTag: {$this->_tag}" : "\n") . - "\nProperties: " . print_r($this->_properties, true) - ); - } - if ($this->isCacheable() && isset($this->modx->elementCache[$this->_tag])) { - $this->_output = $this->modx->elementCache[$this->_tag]; - } else { - $this->_output = $this->_content; - $this->filterOutput(); - } - $this->_processed = true; - - return $this->_result; - } - - - /** - * @return string - */ - public function getTag() - { - return $this->_tag; - } - -} diff --git a/core/components/pdotools/src/Parsing/Tag.php b/core/components/pdotools/src/Parsing/Tag.php new file mode 100644 index 00000000..c66da69c --- /dev/null +++ b/core/components/pdotools/src/Parsing/Tag.php @@ -0,0 +1,48 @@ +filterInput(); + + if ($this->modx->getDebug() === true) { + $this->modx->log( + xPDO::LOG_LEVEL_DEBUG, "Processing Element: " . $this->get('name') . + ($this->_tag ? "\nTag: {$this->_tag}" : "\n") . + "\nProperties: " . print_r($this->_properties, true) + ); + } + if ($this->isCacheable() && isset($this->modx->elementCache[$this->_tag])) { + $this->_output = $this->modx->elementCache[$this->_tag]; + } else { + $this->_output = $this->_content; + $this->filterOutput(); + } + $this->_processed = true; + + return $this->_result; + } + + + /** + * @return string + */ + public function getTag() + { + return $this->_tag; + } + +} diff --git a/core/components/pdotools/model/pdotools/pdomenu.class.php b/core/components/pdotools/src/Support/MenuBuilder.php similarity index 61% rename from core/components/pdotools/model/pdotools/pdomenu.class.php rename to core/components/pdotools/src/Support/MenuBuilder.php index 90998bc7..a679121c 100644 --- a/core/components/pdotools/model/pdotools/pdomenu.class.php +++ b/core/components/pdotools/src/Support/MenuBuilder.php @@ -1,15 +1,24 @@ modx = &$modx; + $this->modx = $modx; - $config = array_merge( - array( + $config += [ 'firstClass' => 'first', 'lastClass' => 'last', 'hereClass' => 'active', @@ -36,12 +44,8 @@ public function __construct(modX & $modx, $config = array()) 'webLinkClass' => '', 'limit' => 0, 'hereId' => 0, - ), - $config, - array( - 'return' => 'data', - ) - ); + ]; + $config['return'] = 'data'; if (empty($config['tplInner']) && !empty($config['tplOuter'])) { $config['tplInner'] = $config['tplOuter']; @@ -50,20 +54,16 @@ public function __construct(modX & $modx, $config = array()) $config['hereId'] = $modx->resource->id; } - $fqn = $modx->getOption('pdoFetch.class', null, 'pdotools.pdofetch', true); - $path = $modx->getOption('pdofetch_class_path', null, MODX_CORE_PATH . 'components/pdotools/model/', true); - if ($pdoClass = $modx->loadClass($fqn, $path, false, true)) { - $this->pdoTools = new $pdoClass($modx, $config); - } else { - return; - } + $modx->services['pdotools_config'] = $config; + $this->pdoTools = $modx->services->get(Fetch::class); + if ($config['hereId']) { - $here = $this->pdoTools->getObject('modResource', $config['hereId'], array('select' => 'id, context_key')); + $here = $this->pdoTools->getObject(modResource::class, ['id' => $config['hereId']], ['select' => 'id,context_key']); if ($here) { - $tmp = $modx->getParentIds($here['id'], 100, array( + $tmp = $modx->getParentIds($here['id'], 100, [ 'context' => $here['context_key'], - )); + ]); $tmp[] = $config['hereId']; $this->parentTree = array_flip($tmp); } @@ -80,7 +80,7 @@ public function __construct(modX & $modx, $config = array()) * * @return mixed */ - public function templateTree($tree = array()) + public function templateTree($tree = []) { $this->tree = $tree; $count = count($tree); @@ -94,7 +94,7 @@ public function templateTree($tree = array()) } $this->level = 1; $row['idx'] = $idx++; - $row['last'] = (integer)$row['idx'] == $count; + $row['last'] = $row['idx'] == $count; $output .= $this->templateBranch($row); } @@ -102,15 +102,15 @@ public function templateTree($tree = array()) if (!empty($output)) { $pls = $this->addWayFinderPlaceholders( - array( + [ 'wrapper' => $output, - 'classes' => ' class="' . $this->pdoTools->config['outerClass'] . '"', - 'classNames' => $this->pdoTools->config['outerClass'], - 'classnames' => $this->pdoTools->config['outerClass'], + 'classes' => ' class="' . $this->pdoTools->config('outerClass') . '"', + 'classNames' => $this->pdoTools->config('outerClass'), + 'classnames' => $this->pdoTools->config('outerClass'), 'level' => $this->level, - ) + ] ); - $output = $this->pdoTools->parseChunk($this->pdoTools->config['tplOuter'], $pls); + $output = $this->pdoTools->parseChunk($this->pdoTools->config('tplOuter'), $pls); } return $output; @@ -124,18 +124,18 @@ public function templateTree($tree = array()) * * @return mixed|string */ - public function templateBranch($row = array()) + public function templateBranch($row = []) { $children = ''; $row['level'] = $this->level; - if (!empty($row['children']) && ($this->isHere($row['id']) || empty($this->pdoTools->config['hideSubMenus'])) && $this->checkResource($row['id'])) { + if (!empty($row['children']) && ($this->isHere($row['id']) || empty($this->pdoTools->config('hideSubMenus'))) && $this->checkResource($row['id'])) { $idx = $this->pdoTools->idx; $this->level++; $count = count($row['children']); foreach ($row['children'] as $v) { $v['idx'] = $idx++; - $v['last'] = (integer)$v['idx'] == $count; + $v['last'] = $v['idx'] == $count; $children .= $this->templateBranch($v); } @@ -145,14 +145,14 @@ public function templateBranch($row = array()) $row['children'] = isset($row['children']) ? count($row['children']) : 0; } - if (!empty($this->pdoTools->config['countChildren'])) { + if (!empty($this->pdoTools->config('countChildren'))) { if ($ids = $this->modx->getChildIds($row['id'])) { $tstart = microtime(true); - $count = $this->modx->getCount('modResource', array( + $count = $this->modx->getCount(modResource::class, [ 'id:IN' => $ids, 'published' => true, 'deleted' => false, - )); + ]); $this->modx->queryTime += microtime(true) - $tstart; $this->modx->executedQueries++; $this->pdoTools->addTime('Got the number of active children for resource "' . $row['id'] . '": ' . $count); @@ -163,14 +163,14 @@ public function templateBranch($row = array()) } if (!empty($children)) { - $pls = $this->addWayFinderPlaceholders(array( + $pls = $this->addWayFinderPlaceholders([ 'wrapper' => $children, - 'classes' => ' class="' . $this->pdoTools->config['innerClass'] . '"', - 'classNames' => $this->pdoTools->config['innerClass'], - 'classnames' => $this->pdoTools->config['innerClass'], + 'classes' => ' class="' . $this->pdoTools->config('innerClass') . '"', + 'classNames' => $this->pdoTools->config('innerClass'), + 'classnames' => $this->pdoTools->config('innerClass'), 'level' => $this->level, - )); - $row['wrapper'] = $this->pdoTools->parseChunk($this->pdoTools->config['tplInner'], $pls); + ]); + $row['wrapper'] = $this->pdoTools->parseChunk($this->pdoTools->config('tplInner'), $pls); } else { $row['wrapper'] = ''; } @@ -187,7 +187,7 @@ public function templateBranch($row = array()) $row['classNames'] = $row['classnames'] = $row['classes'] = ''; } - if (!empty($this->pdoTools->config['useWeblinkUrl']) && $row['class_key'] == 'modWebLink') { + if (!empty($this->pdoTools->config('useWeblinkUrl')) && $row['class_key'] === modWebLink::class) { unset($row['context_key']); $row['link'] = is_numeric(trim($row['content'], '[]~ ')) ? $this->pdoTools->makeUrl((int)trim($row['content'], '[]~ '), $row) @@ -196,14 +196,14 @@ public function templateBranch($row = array()) $row['link'] = $this->pdoTools->makeUrl($row['id'], $row); } - $row['title'] = !empty($this->pdoTools->config['titleOfLinks']) - ? $row[$this->pdoTools->config['titleOfLinks']] + $row['title'] = !empty($this->pdoTools->config('titleOfLinks')) + ? $row[$this->pdoTools->config('titleOfLinks')] : $row['pagetitle']; $tpl = $this->getTpl($row); $row = $this->addWayFinderPlaceholders($row); - return $this->pdoTools->getChunk($tpl, $row, $this->pdoTools->config['fastMode']); + return $this->pdoTools->getChunk($tpl, $row, $this->pdoTools->config('fastMode')); } @@ -227,35 +227,35 @@ public function isHere($id = 0) * * @return string */ - public function getClasses($row = array()) + public function getClasses($row = []) { - $classes = array(); + $classes = []; - if (!empty($this->pdoTools->config['rowClass'])) { - $classes[] = $this->pdoTools->config['rowClass']; + if (!empty($this->pdoTools->config('rowClass'))) { + $classes[] = $this->pdoTools->config('rowClass'); } - if ($row['idx'] == 1 && !empty($this->pdoTools->config['firstClass'])) { - $classes[] = $this->pdoTools->config['firstClass']; - } elseif (!empty($row['last']) && !empty($this->pdoTools->config['lastClass'])) { - $classes[] = $this->pdoTools->config['lastClass']; + if ($row['idx'] == 1 && !empty($this->pdoTools->config('firstClass'))) { + $classes[] = $this->pdoTools->config('firstClass'); + } elseif (!empty($row['last']) && !empty($this->pdoTools->config('lastClass'))) { + $classes[] = $this->pdoTools->config('lastClass'); } - if (!empty($this->pdoTools->config['levelClass'])) { - $classes[] = $this->pdoTools->config['levelClass'] . $row['level']; + if (!empty($this->pdoTools->config('levelClass'))) { + $classes[] = $this->pdoTools->config('levelClass') . $row['level']; } - if ($row['children'] && !empty($this->pdoTools->config['parentClass']) && ($row['level'] < $this->pdoTools->config['level'] || empty($this->pdoTools->config['level']))) { - $classes[] = $this->pdoTools->config['parentClass']; + if ($row['children'] && !empty($this->pdoTools->config('parentClass')) && ($row['level'] < $this->pdoTools->config('level') || empty($this->pdoTools->config('level')))) { + $classes[] = $this->pdoTools->config('parentClass'); } - $row_id = !empty($this->pdoTools->config['useWeblinkUrl']) && is_numeric(trim($row['content'], '[]~ ')) && $row['class_key'] == 'modWebLink' + $row_id = !empty($this->pdoTools->config('useWeblinkUrl')) && is_numeric(trim($row['content'], '[]~ ')) && $row['class_key'] == modWebLink::class ? (int)trim($row['content'], '[]~ ') : $row['id']; - if ($this->isHere($row_id) && !empty($this->pdoTools->config['hereClass'])) { - $classes[] = $this->pdoTools->config['hereClass']; + if ($this->isHere($row_id) && !empty($this->pdoTools->config('hereClass'))) { + $classes[] = $this->pdoTools->config('hereClass'); } - if ($row_id == $this->pdoTools->config['hereId'] && !empty($this->pdoTools->config['selfClass'])) { - $classes[] = $this->pdoTools->config['selfClass']; + if ($row_id == $this->pdoTools->config('hereId') && !empty($this->pdoTools->config('selfClass'))) { + $classes[] = $this->pdoTools->config('selfClass'); } - if (!empty($row['class_key']) && $row['class_key'] == 'modWebLink' && !empty($this->pdoTools->config['webLinkClass'])) { - $classes[] = $this->pdoTools->config['webLinkClass']; + if (!empty($row['class_key']) && $row['class_key'] === modWebLink::class && !empty($this->pdoTools->config('webLinkClass'))) { + $classes[] = $this->pdoTools->config('webLinkClass'); } return implode(' ', $classes); @@ -269,36 +269,36 @@ public function getClasses($row = array()) * * @return mixed */ - public function getTpl($row = array()) + public function getTpl($row = []) { - $row_id = !empty($this->pdoTools->config['useWeblinkUrl']) && $row['class_key'] == 'modWebLink' && is_numeric(trim($row['content'], '[]~ ')) + $row_id = !empty($this->pdoTools->config('useWeblinkUrl')) && $row['class_key'] === modWebLink::class && is_numeric(trim($row['content'], '[]~ ')) ? (int)trim($row['content'], '[]~ ') : $row['id']; - if ($row['level'] == 1 && !empty($this->pdoTools->config['tplStart']) && !empty($this->pdoTools->config['displayStart'])) { + if ($row['level'] === 1 && !empty($this->pdoTools->config('tplStart')) && !empty($this->pdoTools->config('displayStart'))) { $tpl = 'tplStart'; - } elseif ($row['children'] && $row_id == $this->pdoTools->config['hereId'] && !empty($this->pdoTools->config['tplParentRowHere'])) { + } elseif ($row['children'] && $row_id == $this->pdoTools->config('hereId') && !empty($this->pdoTools->config('tplParentRowHere'))) { $tpl = 'tplParentRowHere'; - } elseif ($row['level'] > 1 && $row_id == $this->pdoTools->config['hereId'] && !empty($this->pdoTools->config['tplInnerHere'])) { + } elseif ($row['level'] > 1 && $row_id == $this->pdoTools->config('hereId') && !empty($this->pdoTools->config('tplInnerHere'))) { $tpl = 'tplInnerHere'; - } elseif ($row_id == $this->pdoTools->config['hereId'] && !empty($this->pdoTools->config['tplHere'])) { + } elseif ($row_id == $this->pdoTools->config('hereId') && !empty($this->pdoTools->config('tplHere'))) { $tpl = 'tplHere'; - } elseif ($row['children'] && $this->isHere($row_id) && !empty($this->pdoTools->config['tplParentRowActive'])) { + } elseif ($row['children'] && $this->isHere($row_id) && !empty($this->pdoTools->config('tplParentRowActive'))) { $tpl = 'tplParentRowActive'; - } elseif ($row['children'] && (empty($row['template']) || strpos($row['link_attributes'], 'category') != false) && !empty($this->pdoTools->config['tplCategoryFolder'])) { + } elseif ($row['children'] && (empty($row['template']) || strpos($row['link_attributes'], 'category') != false) && !empty($this->pdoTools->config('tplCategoryFolder'))) { $tpl = 'tplCategoryFolder'; } // It's a typo, but it is left for backward compatibility - elseif ($row['children'] && (empty($row['template']) || strpos($row['link_attributes'], 'category') != false) && !empty($this->pdoTools->config['tplCategoryFolders'])) { + elseif ($row['children'] && (empty($row['template']) || strpos($row['link_attributes'], 'category') != false) && !empty($this->pdoTools->config('tplCategoryFolders'))) { $tpl = 'tplCategoryFolders'; } // --- - elseif ($row['children'] && !empty($this->pdoTools->config['tplParentRow'])) { + elseif ($row['children'] && !empty($this->pdoTools->config('tplParentRow'))) { $tpl = 'tplParentRow'; - } elseif ($row['level'] > 1 && !empty($this->pdoTools->config['tplInnerRow'])) { + } elseif ($row['level'] > 1 && !empty($this->pdoTools->config('tplInnerRow'))) { $tpl = 'tplInnerRow'; } else { return $this->pdoTools->defineChunk($row); } - return $this->pdoTools->config[$tpl]; + return $this->pdoTools->config($tpl); } @@ -309,14 +309,14 @@ public function getTpl($row = array()) * * @return array */ - public function addWayFinderPlaceholders($row = array()) + public function addWayFinderPlaceholders($row = []) { - $pl = $this->pdoTools->config['plPrefix']; + $pl = $this->pdoTools->config('plPrefix'); foreach ($row as $k => $v) { switch ($k) { case 'id': - if (!empty($this->pdoTools->config['rowIdPrefix'])) { - $row[$pl . 'id'] = ' id="' . $this->pdoTools->config['rowIdPrefix'] . $v . '"'; + if (!empty($this->pdoTools->config('rowIdPrefix'))) { + $row[$pl . 'id'] = ' id="' . $this->pdoTools->config('rowIdPrefix') . $v . '"'; } $row[$pl . 'docid'] = $v; break; @@ -349,23 +349,23 @@ public function addWayFinderPlaceholders($row = array()) */ public function checkResource($id) { - $tmp = array(); - if (empty($this->pdoTools->config['showHidden'])) { + $tmp = []; + if (empty($this->pdoTools->config('showHidden'))) { $tmp['hidemenu'] = 0; } - if (empty($this->pdoTools->config['showUnpublished'])) { + if (empty($this->pdoTools->config('showUnpublished'))) { $tmp['published'] = 1; } - if (!empty($this->pdoTools->config['hideUnsearchable'])) { + if (!empty($this->pdoTools->config('hideUnsearchable'))) { $tmp['searchable'] = 1; } if (!empty($tmp)) { $tmp['id'] = $id; - return empty($this->pdoTools->config['checkPermissions']) - ? (bool)$this->modx->getCount('modResource', $tmp) - : (bool)$this->modx->getObject('modResource', $tmp); + return empty($this->pdoTools->config('checkPermissions')) + ? (bool)$this->modx->getCount(modResource::class, $tmp) + : (bool)$this->modx->getObject(modResource::class, $tmp); } return true; diff --git a/core/components/pdotools/model/pdotools/pdopage.class.php b/core/components/pdotools/src/Support/Paginator.php similarity index 61% rename from core/components/pdotools/model/pdotools/pdopage.class.php rename to core/components/pdotools/src/Support/Paginator.php index f2dfa910..a4f07a77 100644 --- a/core/components/pdotools/model/pdotools/pdopage.class.php +++ b/core/components/pdotools/src/Support/Paginator.php @@ -1,10 +1,15 @@ modx = &$modx; - - $fqn = $modx->getOption('pdoTools.class', null, 'pdotools.pdotools', true); - $path = $modx->getOption('pdotools_class_path', null, MODX_CORE_PATH . 'components/pdotools/model/', true); - if ($pdoClass = $modx->loadClass($fqn, $path, false, true)) { - $this->pdoTools = new $pdoClass($modx, $config); - } else { - return; - } + $this->modx = $modx; + $this->pdoTools = new CoreTools($modx, $config); $modx->lexicon->load('pdotools:pdopage'); } @@ -35,70 +33,79 @@ public function __construct(modX & $modx, $config = array()) */ public function loadJsCss() { - $assetsUrl = !empty($this->pdoTools->config['assetsUrl']) - ? $this->pdoTools->config['assetsUrl'] + $assetsUrl = !empty($this->pdoTools->config('assetsUrl')) + ? $this->pdoTools->config('assetsUrl') : MODX_ASSETS_URL . 'components/pdotools/'; - if ($css = trim($this->pdoTools->config['frontend_css'])) { + if ($css = trim($this->pdoTools->config('frontend_css'))) { $this->modx->regClientCSS(str_replace('[[+assetsUrl]]', $assetsUrl, $css)); } - if ($js = trim($this->pdoTools->config['frontend_js'])) { + if ($js = trim($this->pdoTools->config('frontend_js'))) { $this->modx->regClientScript(str_replace('[[+assetsUrl]]', $assetsUrl, $js)); } - $ajaxHistory = $this->pdoTools->config['ajaxHistory'] === '' - ? !in_array($this->pdoTools->config['ajaxMode'], array('scroll', 'button')) - : !empty($this->pdoTools->config['ajaxHistory']); - $limit = $this->pdoTools->config['limit'] > $this->pdoTools->config['maxLimit'] - ? $this->pdoTools->config['maxLimit'] - : $this->pdoTools->config['limit']; - $moreChunk = $this->modx->getOption('ajaxTplMore', $this->pdoTools->config, + $ajaxHistory = $this->pdoTools->config('ajaxHistory') === '' + ? !in_array($this->pdoTools->config('ajaxMode'), ['scroll', 'button']) + : !empty($this->pdoTools->config('ajaxHistory')); + $limit = $this->pdoTools->config('limit') > $this->pdoTools->config('maxLimit') + ? $this->pdoTools->config('maxLimit') + : $this->pdoTools->config('limit'); + $moreChunk = $this->modx->getOption( + 'ajaxTplMore', + $this->pdoTools->config(), '@INLINE ' ); - $moreTpl = $this->pdoTools->getChunk($moreChunk, array('limit' => $limit)); - - $hash = sha1(json_encode($this->pdoTools->config)); - $_SESSION['pdoPage'][$hash] = $this->pdoTools->config; - - $config = array( - 'wrapper' => $this->modx->getOption('ajaxElemWrapper', $this->pdoTools->config, '#pdopage'), - 'rows' => $this->modx->getOption('ajaxElemRows', $this->pdoTools->config, '#pdopage .rows'), - 'pagination' => $this->modx->getOption('ajaxElemPagination', $this->pdoTools->config, - '#pdopage .pagination'), - 'link' => $this->modx->getOption('ajaxElemLink', $this->pdoTools->config, '#pdopage .pagination a'), - 'more' => $this->modx->getOption('ajaxElemMore', $this->pdoTools->config, '#pdopage .btn-more'), + $moreTpl = $this->pdoTools->getChunk($moreChunk, ['limit' => $limit]); + + $hash = sha1(json_encode($this->pdoTools->config())); + $_SESSION['pdoPage'][$hash] = $this->pdoTools->config(); + + $config = [ + 'wrapper' => $this->modx->getOption('ajaxElemWrapper', $this->pdoTools->config(), '#pdopage'), + 'rows' => $this->modx->getOption('ajaxElemRows', $this->pdoTools->config(), '#pdopage .rows'), + 'pagination' => $this->modx->getOption( + 'ajaxElemPagination', + $this->pdoTools->config(), + '#pdopage .pagination' + ), + 'link' => $this->modx->getOption('ajaxElemLink', $this->pdoTools->config(), '#pdopage .pagination a'), + 'more' => $this->modx->getOption('ajaxElemMore', $this->pdoTools->config(), '#pdopage .btn-more'), 'moreTpl' => $moreTpl, - 'mode' => $this->pdoTools->config['ajaxMode'], + 'mode' => $this->pdoTools->config('ajaxMode'), 'history' => (int)$ajaxHistory, - 'pageVarKey' => $this->pdoTools->config['pageVarKey'], + 'pageVarKey' => $this->pdoTools->config('pageVarKey'), 'pageLimit' => $limit, 'assetsUrl' => $assetsUrl, 'connectorUrl' => rtrim($assetsUrl, '/') . '/connector.php', 'pageId' => $this->modx->resource->id, 'hash' => $hash, - 'scrollTop' => (bool)$this->modx->getOption('scrollTop', $this->pdoTools->config, true), - ); + 'scrollTop' => (bool)$this->modx->getOption('scrollTop', $this->pdoTools->config(), true), + ]; - if (empty($this->pdoTools->config['frontend_startup_js'])) { + if (empty($this->pdoTools->config('frontend_startup_js'))) { $this->modx->regClientStartupScript( - '', true + '', + true ); } else { $this->modx->regClientStartupScript( - $this->pdoTools->getChunk($this->pdoTools->config['frontend_startup_js']), true + $this->pdoTools->getChunk($this->pdoTools->config('frontend_startup_js')), + true ); } - if (empty($this->pdoTools->config['frontend_init_js'])) { + if (empty($this->pdoTools->config('frontend_init_js'))) { /** @noinspection Annotator */ $this->modx->regClientScript( - '', true + '', + true ); } else { $this->modx->regClientScript( - $this->pdoTools->getChunk($this->pdoTools->config['frontend_init_js'], array( + $this->pdoTools->getChunk($this->pdoTools->config('frontend_init_js'), [ 'key' => $config['pageVarKey'], 'wrapper' => $config['wrapper'], 'config' => json_encode($config), - )), true + ]), + true ); } } @@ -107,13 +114,13 @@ public function loadJsCss() /** * Redirect user to the first page of pagination * - * @param $isAjax + * @param bool $isAjax * * @return string */ public function redirectToFirst($isAjax = false) { - unset($_GET[$this->pdoTools->config['pageVarKey']]); + unset($_GET[$this->pdoTools->config('pageVarKey')]); unset($_GET[$this->modx->getOption('request_param_alias', null, 'q')]); if (!$isAjax) { $this->modx->sendRedirect( @@ -126,12 +133,12 @@ public function redirectToFirst($isAjax = false) ); return ''; - } else { - $_GET[$this->pdoTools->config['pageVarKey']] = 1; - $_REQUEST = $_GET; - - return $this->pdoTools->runSnippet('pdoPage', $this->pdoTools->config); } + + $_GET[$this->pdoTools->config('pageVarKey')] = 1; + $_REQUEST = $_GET; + + return $this->pdoTools->runSnippet('pdoPage', $this->pdoTools->config()); } @@ -144,13 +151,11 @@ public function getBaseUrl() { if ($this->modx->getOption('friendly_urls')) { $q_var = $this->modx->getOption('request_param_alias', null, 'q'); - $q_val = isset($_REQUEST[$q_var]) - ? $_REQUEST[$q_var] - : ''; + $q_val = $_REQUEST[$q_var] ?? ''; $this->req_var = $q_var; $host = ''; - switch ($this->pdoTools->config['scheme']) { + switch ($this->pdoTools->config('scheme')) { case 'full': $host = $this->modx->getOption('site_url'); break; @@ -160,25 +165,22 @@ public function getBaseUrl() break; case 'https': case 'http': - $host = $this->pdoTools->config['scheme'] . '://' . $this->modx->getOption('http_host') . + $host = $this->pdoTools->config('scheme') . '://' . $this->modx->getOption('http_host') . $this->modx->getOption('base_url'); break; } $url = $host . $q_val; } else { $id_var = $this->modx->getOption('request_param_id', null, 'id'); - $id_val = isset($_GET[$id_var]) - ? $_GET[$id_var] - : $this->modx->getOption('site_start'); + $id_val = $_GET[$id_var] ?? $this->modx->getOption('site_start'); $this->req_var = $id_var; - $url = $this->modx->makeUrl($id_val, '', '', $this->pdoTools->config['scheme']); + $url = $this->modx->makeUrl($id_val, '', '', $this->pdoTools->config('scheme')); } return $url; } - /** * Returns templates link for pagination * @@ -195,35 +197,35 @@ public function makePageLink($url = '', $page = 1, $tpl = '') } $link = $pcre = ''; - if (!empty($this->pdoTools->config['pageLinkScheme'])) { - $pls = $this->pdoTools->makePlaceholders(array( - 'pageVarKey' => $this->pdoTools->config['pageVarKey'], + if (!empty($this->pdoTools->config('pageLinkScheme'))) { + $pls = $this->pdoTools->makePlaceholders([ + 'pageVarKey' => $this->pdoTools->config('pageVarKey'), 'page' => $page, - )); - $link = str_replace($pls['pl'], $pls['vl'], $this->pdoTools->config['pageLinkScheme']); - $pcre = preg_replace('#\d+#', '(\d+)', preg_quote(preg_replace('#\#.*#', '', $link))); + ]); + $link = str_replace($pls['pl'], $pls['vl'], $this->pdoTools->config('pageLinkScheme')); + $pcre = preg_replace('#\d+#', '(\d+)', preg_replace('#\#.*#', '', $link)); } $href = !empty($link) - ? preg_replace('#' . $pcre . '#', '', $url) + ? preg_replace('#' . preg_quote($pcre, '#') . '#', '', $url) : $url; - if ($page > 1 || ($page == 1 && !empty($this->pdoTools->config['ajax']))) { + if ($page > 1 || ($page === 1 && !empty($this->pdoTools->config('ajax')))) { if (!empty($link)) { $href .= $link; } else { $href .= strpos($href, '?') !== false ? '&' : '?'; - $href .= $this->pdoTools->config['pageVarKey'] . '=' . $page; + $href .= $this->pdoTools->config('pageVarKey') . '=' . $page; } } if (!empty($_GET)) { $request = $_GET; - array_walk_recursive($request, function(&$item) { + array_walk_recursive($request, function (&$item) { $item = rawurldecode($item); }); unset($request[$this->req_var]); - unset($request[$this->pdoTools->config['pageVarKey']]); + unset($request[$this->pdoTools->config('pageVarKey')]); if (!empty($request)) { $href .= strpos($href, '?') !== false @@ -237,17 +239,32 @@ public function makePageLink($url = '', $page = 1, $tpl = '') $href = preg_replace("/&(?!amp;)/", "&", $href); } - $data = array( + $data = [ 'page' => $page, 'pageNo' => $page, 'href' => $href, - ); + ]; return !empty($tpl) ? $this->pdoTools->getChunk($tpl, $data) : $href; } + /** + * Creates the correct URL of the page, including folder subdomains. + * @see https://github.com/modx-pro/pdoTools/issues/318 + * + * @param string $uri + * @return string + */ + public function getCanonicalUrl($uri = '') + { + $siteUrl = $this->modx->getOption('site_url'); + if ($this->modx->context->key !== 'web' && !empty(trim($this->modx->getOption('base_url'), ' /'))) { + $siteUrl = strstr($siteUrl, $this->modx->getOption('base_url'), true) . '/'; + } + return $siteUrl . ltrim($uri, '/'); + } /** * Classic pagination: 3,4,5,6,7,8,9,10,11,12,13,14 @@ -260,7 +277,7 @@ public function makePageLink($url = '', $page = 1, $tpl = '') */ public function buildClassicPagination($page = 1, $pages = 5, $url = '') { - $pageLimit = $this->pdoTools->config['pageLimit']; + $pageLimit = $this->pdoTools->config('pageLimit'); if ($pageLimit > $pages) { $pageLimit = 0; @@ -299,10 +316,10 @@ public function buildClassicPagination($page = 1, $pages = 5, $url = '') break; } - if ($page == $i && !empty($this->pdoTools->config['tplPageActive'])) { - $tpl = $this->pdoTools->config['tplPageActive']; - } elseif (!empty($this->pdoTools->config['tplPage'])) { - $tpl = $this->pdoTools->config['tplPage']; + if ($page === $i && !empty($this->pdoTools->config('tplPageActive'))) { + $tpl = $this->pdoTools->config('tplPageActive'); + } elseif (!empty($this->pdoTools->config('tplPage'))) { + $tpl = $this->pdoTools->config('tplPage'); } $pagination .= !empty($tpl) @@ -327,7 +344,7 @@ public function buildClassicPagination($page = 1, $pages = 5, $url = '') */ public function buildModernPagination($page = 1, $pages = 5, $url = '') { - $pageLimit = $this->pdoTools->config['pageLimit']; + $pageLimit = $this->pdoTools->config('pageLimit'); if ($pageLimit >= $pages || $pageLimit < 7) { return $this->buildClassicPagination($page, $pages, $url); @@ -337,13 +354,13 @@ public function buildModernPagination($page = 1, $pages = 5, $url = '') $center = $pageLimit - ($tmp * 2); } - $pagination = array(); + $pagination = []; // Left for ($i = 1; $i <= $left; $i++) { - if ($page == $i && !empty($this->pdoTools->config['tplPageActive'])) { - $tpl = $this->pdoTools->config['tplPageActive']; - } elseif (!empty($this->pdoTools->config['tplPage'])) { - $tpl = $this->pdoTools->config['tplPage']; + if ($page == $i && !empty($this->pdoTools->config('tplPageActive'))) { + $tpl = $this->pdoTools->config('tplPageActive'); + } elseif (!empty($this->pdoTools->config('tplPage'))) { + $tpl = $this->pdoTools->config('tplPage'); } $pagination[$i] = !empty($tpl) ? $this->makePageLink($url, $i, $tpl) @@ -352,10 +369,10 @@ public function buildModernPagination($page = 1, $pages = 5, $url = '') // Right for ($i = $pages - $right + 1; $i <= $pages; $i++) { - if ($page == $i && !empty($this->pdoTools->config['tplPageActive'])) { - $tpl = $this->pdoTools->config['tplPageActive']; - } elseif (!empty($this->pdoTools->config['tplPage'])) { - $tpl = $this->pdoTools->config['tplPage']; + if ($page == $i && !empty($this->pdoTools->config('tplPageActive'))) { + $tpl = $this->pdoTools->config('tplPageActive'); + } elseif (!empty($this->pdoTools->config('tplPage'))) { + $tpl = $this->pdoTools->config('tplPage'); } $pagination[$i] = !empty($tpl) ? $this->makePageLink($url, $i, $tpl) @@ -366,10 +383,10 @@ public function buildModernPagination($page = 1, $pages = 5, $url = '') if ($page <= $left) { $i = $left + 1; while ($i <= $center + $left) { - if ($i == $center + $left && !empty($this->pdoTools->config['tplPageSkip'])) { - $tpl = $this->pdoTools->config['tplPageSkip']; + if ($i == $center + $left && !empty($this->pdoTools->config('tplPageSkip'))) { + $tpl = $this->pdoTools->config('tplPageSkip'); } else { - $tpl = $this->pdoTools->config['tplPage']; + $tpl = $this->pdoTools->config('tplPage'); } $pagination[$i] = !empty($tpl) @@ -380,10 +397,10 @@ public function buildModernPagination($page = 1, $pages = 5, $url = '') } elseif ($page > $pages - $right) { $i = $pages - $right - $center + 1; while ($i <= $pages - $right) { - if ($i == $pages - $right - $center + 1 && !empty($this->pdoTools->config['tplPageSkip'])) { - $tpl = $this->pdoTools->config['tplPageSkip']; + if ($i == $pages - $right - $center + 1 && !empty($this->pdoTools->config('tplPageSkip'))) { + $tpl = $this->pdoTools->config('tplPageSkip'); } else { - $tpl = $this->pdoTools->config['tplPage']; + $tpl = $this->pdoTools->config('tplPage'); } $pagination[$i] = !empty($tpl) @@ -395,57 +412,57 @@ public function buildModernPagination($page = 1, $pages = 5, $url = '') if ($page - $center < $left) { $i = $left + 1; while ($i <= $center + $left) { - if ($page == $i && !empty($this->pdoTools->config['tplPageActive'])) { - $tpl = $this->pdoTools->config['tplPageActive']; - } elseif (!empty($this->pdoTools->config['tplPage'])) { - $tpl = $this->pdoTools->config['tplPage']; + if ($page == $i && !empty($this->pdoTools->config('tplPageActive'))) { + $tpl = $this->pdoTools->config('tplPageActive'); + } elseif (!empty($this->pdoTools->config('tplPage'))) { + $tpl = $this->pdoTools->config('tplPage'); } $pagination[$i] = !empty($tpl) ? $this->makePageLink($url, $i, $tpl) : ''; $i++; } - if (!empty($this->pdoTools->config['tplPageSkip'])) { + if (!empty($this->pdoTools->config('tplPageSkip'))) { $key = ($page + 1 == $left + $center) ? $pages - $right + 1 : $left + $center; - $pagination[$key] = $this->pdoTools->getChunk($this->pdoTools->config['tplPageSkip']); + $pagination[$key] = $this->pdoTools->getChunk($this->pdoTools->config('tplPageSkip')); } } elseif ($page + $center - 1 > $pages - $right) { $i = $pages - $right - $center + 1; while ($i <= $pages - $right) { - if ($page == $i && !empty($this->pdoTools->config['tplPageActive'])) { - $tpl = $this->pdoTools->config['tplPageActive']; - } elseif (!empty($this->pdoTools->config['tplPage'])) { - $tpl = $this->pdoTools->config['tplPage']; + if ($page === $i && !empty($this->pdoTools->config('tplPageActive'))) { + $tpl = $this->pdoTools->config('tplPageActive'); + } elseif (!empty($this->pdoTools->config('tplPage'))) { + $tpl = $this->pdoTools->config('tplPage'); } $pagination[$i] = !empty($tpl) ? $this->makePageLink($url, $i, $tpl) : ''; $i++; } - if (!empty($this->pdoTools->config['tplPageSkip'])) { + if (!empty($this->pdoTools->config('tplPageSkip'))) { $key = ($page - 1 == $pages - $right - $center + 1) ? $left : $pages - $right - $center + 1; - $pagination[$key] = $this->pdoTools->getChunk($this->pdoTools->config['tplPageSkip']); + $pagination[$key] = $this->pdoTools->getChunk($this->pdoTools->config('tplPageSkip')); } } else { $tmp = (integer)floor(($center - 1) / 2); $i = $page - $tmp; while ($i < $page - $tmp + $center) { - if ($page == $i && !empty($this->pdoTools->config['tplPageActive'])) { - $tpl = $this->pdoTools->config['tplPageActive']; - } elseif (!empty($this->pdoTools->config['tplPage'])) { - $tpl = $this->pdoTools->config['tplPage']; + if ($page === $i && !empty($this->pdoTools->config('tplPageActive'))) { + $tpl = $this->pdoTools->config('tplPageActive'); + } elseif (!empty($this->pdoTools->config('tplPage'))) { + $tpl = $this->pdoTools->config('tplPage'); } $pagination[$i] = !empty($tpl) ? $this->makePageLink($url, $i, $tpl) : ''; $i++; } - if (!empty($this->pdoTools->config['tplPageSkip'])) { - $pagination[$left] = $pagination[$pages - $right + 1] = $this->pdoTools->getChunk($this->pdoTools->config['tplPageSkip']); + if (!empty($this->pdoTools->config('tplPageSkip'))) { + $pagination[$left] = $pagination[$pages - $right + 1] = $this->pdoTools->getChunk($this->pdoTools->config('tplPageSkip')); } } } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..aca43558 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1943 @@ +{ + "name": "pdoTools", + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + } + } + }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true + }, + "async": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz", + "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "body": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", + "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", + "dev": true, + "requires": { + "continuable-cache": "^0.3.1", + "error": "^7.0.0", + "raw-body": "~1.1.0", + "safe-json-parse": "~1.0.1" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "dev": true, + "requires": { + "pako": "~0.2.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", + "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", + "dev": true + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + } + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "clean-css": { + "version": "3.4.28", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz", + "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=", + "dev": true, + "requires": { + "commander": "2.8.x", + "source-map": "0.4.x" + } + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "commander": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", + "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", + "dev": true, + "requires": { + "graceful-readlink": ">= 1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "continuable-cache": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", + "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", + "dev": true + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "error": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz", + "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==", + "dev": true, + "requires": { + "string-template": "~0.2.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", + "dev": true + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "findup-sync": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", + "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", + "dev": true, + "requires": { + "glob": "~5.0.0" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + } + }, + "flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "dev": true, + "requires": { + "globule": "^1.0.0" + } + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "getobject": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.2.tgz", + "integrity": "sha512-2zblDBaFcb3rB4rF77XVnuINOE2h2k/OnqXAiy0IrTxUfV1iFp3la33oAQVY9pCpWU268WFYVt2t71hlMuLsOg==", + "dev": true + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globule": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.3.tgz", + "integrity": "sha512-mb1aYtDbIjTu4ShMB85m3UzjX9BVKe9WCzsnfMSZk+K5GpIbBOexgg4PPCt5eHDEG5/ZQAUX2Kct02zfiPLsKg==", + "dev": true, + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + } + }, + "graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "dev": true + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, + "grunt": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.4.1.tgz", + "integrity": "sha512-ZXIYXTsAVrA7sM+jZxjQdrBOAg7DyMUplOMhTaspMRExei+fD0BTwdWXnn0W5SXqhb/Q/nlkzXclSi3IH55PIA==", + "dev": true, + "requires": { + "dateformat": "~3.0.3", + "eventemitter2": "~0.4.13", + "exit": "~0.1.2", + "findup-sync": "~0.3.0", + "glob": "~7.1.6", + "grunt-cli": "~1.4.2", + "grunt-known-options": "~2.0.0", + "grunt-legacy-log": "~3.0.0", + "grunt-legacy-util": "~2.0.1", + "iconv-lite": "~0.4.13", + "js-yaml": "~3.14.0", + "minimatch": "~3.0.4", + "mkdirp": "~1.0.4", + "nopt": "~3.0.6", + "rimraf": "~3.0.2" + }, + "dependencies": { + "grunt-cli": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz", + "integrity": "sha512-9Dtx/AhVeB4LYzsViCjUQkd0Kw0McN2gYpdmGYKtE2a5Yt7v1Q+HYZVWhqXc/kGnxlMtqKDxSwotiGeFmkrCoQ==", + "dev": true, + "requires": { + "grunt-known-options": "~2.0.0", + "interpret": "~1.1.0", + "liftup": "~3.0.1", + "nopt": "~4.0.1", + "v8flags": "~3.2.0" + }, + "dependencies": { + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + } + } + } + } + }, + "grunt-banner": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/grunt-banner/-/grunt-banner-0.6.0.tgz", + "integrity": "sha1-P4eQIdEj+linuloLb7a+QStYhaw=", + "dev": true, + "requires": { + "chalk": "^1.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "grunt-contrib-cssmin": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/grunt-contrib-cssmin/-/grunt-contrib-cssmin-1.0.2.tgz", + "integrity": "sha1-FzTL09hMpzZHWLflj/GOUqpgu3Y=", + "dev": true, + "requires": { + "chalk": "^1.0.0", + "clean-css": "~3.4.2", + "maxmin": "^1.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "grunt-contrib-uglify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-2.3.0.tgz", + "integrity": "sha1-s9AmDr3WzvoS/y+Onh4ln33kIW8=", + "dev": true, + "requires": { + "chalk": "^1.0.0", + "maxmin": "^1.1.0", + "object.assign": "^4.0.4", + "uglify-js": "~2.8.21", + "uri-path": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "grunt-contrib-watch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.1.0.tgz", + "integrity": "sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg==", + "dev": true, + "requires": { + "async": "^2.6.0", + "gaze": "^1.1.0", + "lodash": "^4.17.10", + "tiny-lr": "^1.1.1" + }, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + } + } + }, + "grunt-known-options": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz", + "integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==", + "dev": true + }, + "grunt-legacy-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz", + "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==", + "dev": true, + "requires": { + "colors": "~1.1.2", + "grunt-legacy-log-utils": "~2.1.0", + "hooker": "~0.2.3", + "lodash": "~4.17.19" + } + }, + "grunt-legacy-log-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz", + "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==", + "dev": true, + "requires": { + "chalk": "~4.1.0", + "lodash": "~4.17.19" + } + }, + "grunt-legacy-util": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz", + "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==", + "dev": true, + "requires": { + "async": "~3.2.0", + "exit": "~0.1.2", + "getobject": "~1.0.0", + "hooker": "~0.2.3", + "lodash": "~4.17.21", + "underscore.string": "~3.3.5", + "which": "~2.0.2" + }, + "dependencies": { + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "gzip-size": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-1.0.0.tgz", + "integrity": "sha1-Zs+LEBBHInuVus5uodoMF37Vwi8=", + "dev": true, + "requires": { + "browserify-zlib": "^0.1.4", + "concat-stream": "^1.4.1" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hooker": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", + "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", + "dev": true + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "http-parser-js": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.5.tgz", + "integrity": "sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-core-module": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true + }, + "liftup": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz", + "integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==", + "dev": true, + "requires": { + "extend": "^3.0.2", + "findup-sync": "^4.0.0", + "fined": "^1.2.0", + "flagged-respawn": "^1.0.1", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.1", + "rechoir": "^0.7.0", + "resolve": "^1.19.0" + }, + "dependencies": { + "findup-sync": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", + "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^4.0.2", + "resolve-dir": "^1.0.1" + } + } + } + }, + "livereload-js": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", + "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==", + "dev": true + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "maxmin": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-1.1.0.tgz", + "integrity": "sha1-cTZehKmd2Piz99X94vANHn9zvmE=", + "dev": true, + "requires": { + "chalk": "^1.0.0", + "figures": "^1.0.1", + "gzip-size": "^1.0.0", + "pretty-bytes": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + } + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-inspect": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.1.tgz", + "integrity": "sha512-If7BjFlpkzzBeV1cqgT3OSWT3azyoxDGajR+iGnFBfVV2EWyDyWaZZW2ERDjUaY2QM8i5jI3Sj7mhsM4DDAqWA==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "requires": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + }, + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pretty-bytes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", + "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1", + "meow": "^3.1.0" + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "qs": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.2.tgz", + "integrity": "sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "raw-body": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", + "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", + "dev": true, + "requires": { + "bytes": "1", + "string_decoder": "0.10" + }, + "dependencies": { + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "requires": { + "resolve": "^1.9.0" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "requires": { + "align-text": "^0.1.1" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-json-parse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", + "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", + "dev": true + }, + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + }, + "string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tiny-lr": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", + "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", + "dev": true, + "requires": { + "body": "^5.1.0", + "debug": "^3.1.0", + "faye-websocket": "~0.10.0", + "livereload-js": "^2.3.0", + "object-assign": "^4.1.0", + "qs": "^6.4.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "underscore.string": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", + "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==", + "dev": true, + "requires": { + "sprintf-js": "^1.0.3", + "util-deprecate": "^1.0.2" + } + }, + "uri-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz", + "integrity": "sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + }, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + } + } + } + } +} diff --git a/package.json b/package.json index deb41e87..0f402cd3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "pdoTools", - "description": "Small library for creating fast snippets for MODX Revolution that works through PDO", + "name": "pdo-tools", + "description": "Build assets of library for creating fast snippets for MODX Revolution", "devDependencies": { "grunt": "^1.0.1", "grunt-banner": "^0.6.0",