/** * @static * @param xPDO|modX $modx * @return array|mixed */ public static function loadCache(xPDO &$modx) { if (!$modx->getCacheManager()) { return array(); } $cacheKey = 'extension-packages'; $cache = $modx->cacheManager->get($cacheKey, array(xPDO::OPT_CACHE_KEY => $modx->getOption('cache_extension_packages_key', null, 'namespaces'), xPDO::OPT_CACHE_HANDLER => $modx->getOption('cache_extension_packages_handler', null, $modx->getOption(xPDO::OPT_CACHE_HANDLER)), xPDO::OPT_CACHE_FORMAT => (int) $modx->getOption('cache_extension_packages_format', null, $modx->getOption(xPDO::OPT_CACHE_FORMAT, null, xPDOCacheManager::CACHE_PHP)))); if (empty($cache)) { $cache = $modx->cacheManager->generateExtensionPackagesCache($cacheKey); } return $cache; }
/** * Write objects preserved during install() to file for use by uninstall(). * * @return boolean Indicates if the preserved file was successfully written. */ public function writePreserved() { $written = false; if (!empty($this->_preserved)) { $content = var_export($this->_preserved, true); $cacheManager = $this->xpdo->getCacheManager(); if ($content && $cacheManager) { $fileName = $this->path . $this->signature . '/preserved.php'; $content = "<?php return {$content};"; if (!($written = $cacheManager->writeFile($fileName, $content))) { $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Error writing preserved objects to ' . $fileName); } } } return $written; }
define('MODX_BUILD_DIR', MODX_BASE_PATH . '_build/'); } /* get properties */ $properties = array(); $f = dirname(__FILE__) . '/build.properties.php'; $included = false; if (file_exists($f)) { $included = @(include $f); } if (!$included) { die('build.properties.php was not found. Please make sure you have created one using the template of build.properties.sample.php.'); } unset($f, $included); /* instantiate xpdo instance */ $xpdo = new xPDO(XPDO_DSN, XPDO_DB_USER, XPDO_DB_PASS, array(xPDO::OPT_TABLE_PREFIX => XPDO_TABLE_PREFIX, xPDO::OPT_CACHE_PATH => MODX_CORE_PATH . 'cache/'), array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING)); $cacheManager = $xpdo->getCacheManager(); $xpdo->setLogLevel(xPDO::LOG_LEVEL_INFO); $xpdo->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML'); $xpdo->loadClass('transport.xPDOTransport', XPDO_CORE_PATH, true, true); $packageDirectory = MODX_CORE_PATH . 'packages/'; $xpdo->log(xPDO::LOG_LEVEL_INFO, 'Beginning build script processes...'); flush(); /* remove pre-existing package files and directory */ if (file_exists($packageDirectory . 'core.transport.zip')) { @unlink($packageDirectory . 'core.transport.zip'); } if (file_exists($packageDirectory . 'core') && is_dir($packageDirectory . 'core')) { $cacheManager->deleteTree($packageDirectory . 'core', array('deleteTop' => true, 'skipDirs' => false, 'extensions' => '*')); } if (!file_exists($packageDirectory . 'core') && !file_exists($packageDirectory . 'core.transport.zip')) { $xpdo->log(xPDO::LOG_LEVEL_INFO, 'Removed pre-existing core/ and core.transport.zip.');
/** * Remove the persistent instance of an object permanently. * * Deletes the persistent object instance stored in the database when * called, including any dependent objects defined by composite foreign key * relationships. * * @todo Implement some way to reassign ownership of related composite * objects when remove is called, perhaps by passing another object * instance as an optional parameter, or creating a separate method. * * @param array $ancestors Keeps track of classes which have already been * removed to prevent loop with circular references. * @return boolean Returns true on success, false on failure. */ public function remove(array $ancestors = array()) { $result = false; $pk = $this->getPrimaryKey(); if ($pk && $this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) { if (!empty($this->_composites)) { $current = array($this->_class, $this->_alias); foreach ($this->_composites as $compositeAlias => $composite) { if (in_array($compositeAlias, $ancestors) || in_array($composite['class'], $ancestors)) { continue; } if ($composite['cardinality'] === 'many') { if ($many = $this->getMany($compositeAlias)) { /** @var xPDOObject $one */ foreach ($many as $one) { $ancestors[] = $compositeAlias; $newAncestors = $ancestors + $current; if (!$one->remove($newAncestors)) { $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error removing dependent object: " . print_r($one->toArray('', true), true)); } } unset($many); } } elseif ($one = $this->getOne($compositeAlias)) { $ancestors[] = $compositeAlias; $newAncestors = $ancestors + $current; if (!$one->remove($newAncestors)) { $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error removing dependent object: " . print_r($one->toArray('', true), true)); } unset($one); } } } $delete = $this->xpdo->newQuery($this->_class); $delete->command('DELETE'); $delete->where($pk); // $delete->limit(1); $stmt = $delete->prepare(); if (is_object($stmt)) { $tstart = microtime(true); if (!($result = $stmt->execute())) { $this->xpdo->queryTime += microtime(true) - $tstart; $this->xpdo->executedQueries++; $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Could not delete from ' . $this->_table . '; primary key specified was ' . print_r($pk, true) . "\n" . print_r($stmt->errorInfo(), true)); } else { $this->xpdo->queryTime += microtime(true) - $tstart; $this->xpdo->executedQueries++; $callback = $this->getOption(xPDO::OPT_CALLBACK_ON_REMOVE); if ($callback && is_callable($callback)) { call_user_func($callback, array('className' => $this->_class, 'criteria' => $delete, 'object' => $this)); } if ($this->xpdo->_cacheEnabled && $this->xpdo->getOption('cache_db', null, false)) { /** @var xPDOCache $dbCache */ $dbCache = $this->xpdo->getCacheManager()->getCacheProvider($this->getOption('cache_db_key', null, 'db'), array(xPDO::OPT_CACHE_KEY => $this->getOption('cache_db_key', null, 'db'), xPDO::OPT_CACHE_HANDLER => $this->getOption(xPDO::OPT_CACHE_DB_HANDLER, null, $this->getOption(xPDO::OPT_CACHE_HANDLER, null, 'cache.xPDOFileCache')), xPDO::OPT_CACHE_FORMAT => (int) $this->getOption('cache_db_format', null, $this->getOption(xPDO::OPT_CACHE_FORMAT, null, xPDOCacheManager::CACHE_PHP)), xPDO::OPT_CACHE_EXPIRES => (int) $this->getOption(xPDO::OPT_CACHE_DB_EXPIRES, null, $this->getOption(xPDO::OPT_CACHE_EXPIRES, null, 0)), xPDO::OPT_CACHE_PREFIX => $this->getOption('cache_db_prefix', null, xPDOCacheManager::CACHE_DIR))); if (!$dbCache->delete($this->_class, array('multiple_object_delete' => true))) { $this->xpdo->log(xPDO::LOG_LEVEL_WARN, "Could not remove cache entries for {$this->_class}", '', __METHOD__, __FILE__, __LINE__); } } $this->xpdo->log(xPDO::LOG_LEVEL_INFO, "Removed {$this->_class} instance with primary key " . print_r($pk, true)); } } else { $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Could not build criteria to delete from ' . $this->_table . '; primary key specified was ' . print_r($pk, true)); } } return $result; }
/** * Clear the caches of all sources * @param array $options * @return void */ public function clearCache(array $options = array()) { /** @var modCacheManager $cacheManager */ $cacheManager = $this->xpdo->getCacheManager(); if (empty($cacheManager)) { return; } $c = $this->xpdo->newQuery('modContext'); $c->select($this->xpdo->escape('key')); $options[xPDO::OPT_CACHE_KEY] = $this->getOption('cache_media_sources_key', $options, 'media_sources'); $options[xPDO::OPT_CACHE_HANDLER] = $this->getOption('cache_media_sources_handler', $options, $this->getOption(xPDO::OPT_CACHE_HANDLER, $options)); $options[xPDO::OPT_CACHE_FORMAT] = (int) $this->getOption('cache_media_sources_format', $options, $this->getOption(xPDO::OPT_CACHE_FORMAT, $options, xPDOCacheManager::CACHE_PHP)); $options[xPDO::OPT_CACHE_ATTEMPTS] = (int) $this->getOption('cache_media_sources_attempts', $options, $this->getOption(xPDO::OPT_CACHE_ATTEMPTS, $options, 10)); $options[xPDO::OPT_CACHE_ATTEMPT_DELAY] = (int) $this->getOption('cache_media_sources_attempt_delay', $options, $this->getOption(xPDO::OPT_CACHE_ATTEMPT_DELAY, $options, 1000)); if ($c->prepare() && $c->stmt->execute()) { while ($row = $c->stmt->fetch(PDO::FETCH_ASSOC)) { if ($row && !empty($row['key'])) { $cacheManager->delete($row['key'] . '/source', $options); } } } }
/** * Transfers the package from one directory to another. * * @access public * @param string $sourceFile The file to transfer. * @param string $targetDir The directory to transfer into. * @return boolean True if successful. */ public function transferPackage($sourceFile, $targetDir) { $transferred = false; $content = ''; if (is_dir($targetDir) && is_writable($targetDir)) { if (!is_array($this->xpdo->version)) { $this->xpdo->getVersionData(); } $productVersion = $this->xpdo->version['code_name'] . '-' . $this->xpdo->version['full_version']; $source = $this->get('service_url') . $sourceFile . (strpos($sourceFile, '?') !== false ? '&' : '?') . 'revolution_version=' . $productVersion; /* see if user has allow_url_fopen on and is not behind a proxy */ $proxyHost = $this->xpdo->getOption('proxy_host', null, ''); if (ini_get('allow_url_fopen') && empty($proxyHost)) { if ($handle = @fopen($source, 'rb')) { $filesize = @filesize($source); $memory_limit = @ini_get('memory_limit'); if (!$memory_limit) { $memory_limit = '8M'; } $byte_limit = $this->_bytes($memory_limit) * 0.5; if (strpos($source, '://') !== false || $filesize > $byte_limit) { $content = @file_get_contents($source); } else { $content = @fread($handle, $filesize); } @fclose($handle); } else { $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, $this->xpdo->lexicon('package_err_file_read', array('source' => $source))); } /* if not, try curl */ } else { if (function_exists('curl_init')) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $source); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 180); $safeMode = @ini_get('safe_mode'); $openBasedir = @ini_get('open_basedir'); if (empty($safeMode) && empty($openBasedir)) { curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); } $proxyHost = $this->xpdo->getOption('proxy_host', null, ''); if (!empty($proxyHost)) { $proxyPort = $this->xpdo->getOption('proxy_port', null, ''); curl_setopt($ch, CURLOPT_PROXY, $proxyHost); curl_setopt($ch, CURLOPT_PROXYPORT, $proxyPort); $proxyUsername = $this->xpdo->getOption('proxy_username', null, ''); if (!empty($proxyUsername)) { $proxyAuth = $this->xpdo->getOption('proxy_auth_type', null, 'BASIC'); $proxyAuth = $proxyAuth == 'NTLM' ? CURLAUTH_NTLM : CURLAUTH_BASIC; curl_setopt($ch, CURLOPT_PROXYAUTH, $proxyAuth); $proxyPassword = $this->xpdo->getOption('proxy_password', null, ''); $up = $proxyUsername . (!empty($proxyPassword) ? ':' . $proxyPassword : ''); curl_setopt($ch, CURLOPT_PROXYUSERPWD, $up); } } $content = curl_exec($ch); curl_close($ch); /* and as last-ditch resort, try fsockopen */ } else { $content = $this->_getByFsockopen($source); } } if ($content) { if ($cacheManager = $this->xpdo->getCacheManager()) { $filename = $this->signature . '.transport.zip'; $target = $targetDir . $filename; $transferred = $cacheManager->writeFile($target, $content); } } else { $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'MODX could not download the file. You must enable allow_url_fopen, cURL or fsockopen to use remote transport packaging.'); } } else { $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, $this->xpdo->lexicon('package_err_target_write', array('targetDir' => $targetDir))); } return $transferred; }
/** * Clear all post caches * * @static * @param xPDO $xpdo A reference to the xPDO|modX instance * @return bool True if cleared */ public static function clearAllCache(xPDO $xpdo) { $xpdo->getCacheManager(); return $xpdo->cacheManager->delete('discuss/post/'); }