/** * Gets a list of database backups * @return array Objects of backups * @throws InternalErrorException */ public static function index() { if (!is_readable(BACKUPS)) { throw new InternalErrorException(__d('database_backup', 'File or directory {0} not readable', rtr(BACKUPS))); } //Gets all files $files = array_values((new Folder(BACKUPS))->read()[1]); //Parses files $files = array_filter(array_map(function ($file) { preg_match('/(\\d{14})?\\.(sql|sql\\.gz|sql\\.bz2)$/i', $file, $matches); if (empty($matches[2])) { return false; } //If it cannot detect the date from the filename, it tries to find // the last modified date of the file if (!empty($matches[1])) { $datetime = preg_replace('/(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})/', '$1-$2-$3 $4:$5:$6', $matches[1]); } else { $datetime = date('Y-m-d H:i:s', filemtime(BACKUPS . DS . $file)); } return (object) ['filename' => $file, 'extension' => $matches[2], 'size' => filesize(BACKUPS . DS . $file), 'compression' => getCompression($matches[2]), 'datetime' => new FrozenTime($datetime)]; }, $files)); if (empty($files)) { return []; } //Re-orders, using the datetime value usort($files, function ($a, $b) { return $b->datetime >= $a->datetime; }); return $files; }
/** * Internal method to download a file * @param string $path File path * @param bool $force If `true`, it forces the download * @return \Cake\Network\Response * @throws InternalErrorException */ protected function _download($path, $force = true) { if (!is_readable($path)) { throw new InternalErrorException(__d('me_tools', 'File or directory {0} not readable', rtr($path))); } $this->response->file($path, ['download' => !empty($force)]); return $this->response; }
/** * Gets all static pages * @return array Static pages * @uses MeCms\Core\Plugin::all() * @uses title() */ public static function all() { //Adds all plugins to paths, adding first MeCms $paths = array_map(function ($plugin) { return firstValue(App::path('Template', $plugin)) . 'StaticPages'; }, Plugin::all()); //Adds APP to paths array_unshift($paths, firstValue(App::path('Template')) . 'StaticPages'); $pages = []; //Gets all static pages foreach ($paths as $path) { $pages = am($pages, array_map(function ($file) use($path) { return (object) ['filename' => pathinfo($file, PATHINFO_FILENAME), 'path' => rtr($file), 'slug' => preg_replace('/\\.ctp$/', '', preg_replace(sprintf('/^%s/', preg_quote($path . DS, DS)), null, $file)), 'title' => self::title(pathinfo($file, PATHINFO_FILENAME)), 'modified' => new FrozenTime(filemtime($file))]; }, (new Folder($path))->findRecursive('^.+\\.ctp$', true))); } return $pages; }
/** * Creates a symbolic link * @param string $origin Origin file or directory * @param string $target Target link * @return bool */ public function createLink($origin, $target) { //Checks if the origin file/directory is readable if (!is_readable($origin)) { $this->err(__d('me_tools', 'File or directory {0} not readable', rtr($origin))); return false; } //Checks if the link already exists if (file_exists($target)) { $this->verbose(__d('me_tools', 'File or directory {0} already exists', rtr($target))); return false; } //Checks if the target directory is writeable if (!is_writable(dirname($target))) { $this->err(__d('me_tools', 'File or directory {0} not writeable', rtr(dirname($target)))); return false; } return symlink($origin, $target); }
/** * Called after the controller's `beforeFilter()` method, but before the * controller executes the current action handler * @param \Cake\Event\Event $event Event instance * @return void * @uses configure() * @throws InternalErrorException */ public function startup(\Cake\Event\Event $event) { //Checks for KCFinder if (!is_readable(WWW_ROOT . 'vendor' . DS . 'kcfinder' . DS . 'index.php')) { throw new InternalErrorException(__d('me_tools', '{0} is not available', 'KCFinder')); } //Checks for the files directory (`APP/webroot/files`) if (!folderIsWriteable(UPLOADED)) { throw new InternalErrorException(__d('me_tools', 'File or directory {0} not writeable', rtr(UPLOADED))); } //Configures KCFinder $this->configure(); }
/** * Deletes a log. * If there's even a serialized log copy, it also deletes that. * @param string $filename Filename * @return \Cake\Network\Response|null * @throws InternalErrorException * @uses _path() */ public function delete($filename) { $this->request->allowMethod(['post', 'delete']); $log = $this->_path($filename); if (!is_writeable($log)) { throw new InternalErrorException(__d('me_tools', 'File or directory {0} not writeable', rtr($log))); } $success = (new File($log))->delete(); $serialized = $this->_path($filename, true); //It also deletes the serialized log copy, where such exists if (file_exists($serialized)) { if (!is_writeable($serialized)) { throw new InternalErrorException(__d('me_tools', 'File or directory {0} not writeable', rtr($serialized))); } if (!(new File($serialized))->delete()) { $success = false; } } if ($success) { $this->Flash->success(__d('me_cms', 'The operation has been performed correctly')); } else { $this->Flash->error(__d('me_cms', 'The operation has not been performed correctly')); } return $this->redirect(['action' => 'index']); }
/** * System checkup * @return void * @uses MeCms\Core\Plugin::all() * @uses MeCms\Core\Plugin::path() * @uses MeTools\Utility\Apache::module() * @uses MeTools\Utility\Apache::version() */ public function checkup() { $checkup['apache'] = ['expires' => Apache::module('mod_expires'), 'rewrite' => Apache::module('mod_rewrite'), 'version' => Apache::version()]; $checkup['backups'] = ['path' => rtr(Configure::read('MysqlBackup.target') . DS), 'writeable' => folderIsWriteable(Configure::read('MysqlBackup.target'))]; $checkup['cache'] = Cache::enabled(); //Checks for PHP's extensions foreach (['exif', 'imagick', 'mcrypt', 'zip'] as $extension) { $checkup['phpExtensions'][$extension] = extension_loaded($extension); } $checkup['plugins'] = ['cakephp' => Configure::version(), 'mecms' => trim(file_get_contents(Plugin::path(MECMS, 'version')))]; //Gets plugins versions foreach (Plugin::all(['exclude' => MECMS]) as $plugin) { $file = Plugin::path($plugin, 'version', true); if ($file) { $checkup['plugins']['plugins'][$plugin] = trim(file_get_contents($file)); } else { $checkup['plugins']['plugins'][$plugin] = __d('me_cms', 'n.a.'); } } //Checks for temporary directories foreach ([LOGS, TMP, Configure::read('Assets.target'), CACHE, LOGIN_LOGS, Configure::read('Thumbs.target')] as $path) { $checkup['temporary'][] = ['path' => rtr($path), 'writeable' => folderIsWriteable($path)]; } //Checks for webroot directories foreach ([BANNERS, PHOTOS, WWW_ROOT . 'files', WWW_ROOT . 'fonts'] as $path) { $checkup['webroot'][] = ['path' => rtr($path), 'writeable' => folderIsWriteable($path)]; } array_walk($checkup, function ($value, $key) { $this->set($key, $value); }); }
/** * Sets permissions on directories * @param bool $force Forces settings * @return void * @uses $paths */ public function setPermissions($force = false) { $error = false; foreach ($this->paths as $path) { if ((new Folder())->chmod($path, 0777, true)) { $this->verbose(__d('me_tools', 'Setted permissions on {0}', rtr($path))); } else { $this->err(__d('me_tools', 'Failed to set permissions on {0}', rtr($path))); $error = true; } } //In case of error, asks for sudo if ($error && which('sudo')) { $command = sprintf('sudo chmod -R 777 %s', implode(' ', $this->paths)); if ($this->param('force') || $force) { exec($command); return; } $ask = $this->in(__d('me_tools', 'Some directories were not created. Try again using {0}?', 'sudo'), ['Y', 'n'], 'Y'); if (in_array($ask, ['Y', 'y'])) { exec($command); } } }