예제 #1
0
 public function postModule(PostModuleEvent $event)
 {
     $pageModuleWrapper = $event->getModuleWrapper();
     $queryCount = $event->getExtra('module_profiler.query_count');
     $time = microtime(true) - $event->getExtra('module_profiler.time');
     $userTime = Helper::getCpuTime('u') - $event->getExtra('module_profiler.user_time');
     $systemTime = Helper::getCpuTime('s') - $event->getExtra('module_profiler.system_time');
     $memoryUsage = memory_get_usage(true) - $event->getExtra('module_profiler.memory_usage');
     $sqlQueries = $queryCount !== null ? Propel::getQueryCount() - $queryCount : null;
     if ($userTime + $systemTime > $this->cpuLimit || $time > $this->timeLimit) {
         $this->logger->warning('Module generation time exceeded limit');
     }
     if ($memoryUsage > $this->memoryLimit) {
         $this->logger->warning('Module memory usage exceeded limit');
     }
     if ($sqlQueries > $this->sqlLimit) {
         $this->logger->warning('Module sql query count exceeded limit');
     }
     // add module debug info
     $this->moduleDebugInfo[] = array($pageModuleWrapper->getName(), $pageModuleWrapper->getClassName(), $pageModuleWrapper->getTemplate(), $pageModuleWrapper->getTarget(), (bool) $event->getExtra('module_cacher.cached'), round($time * 1000.0), round(($userTime + $systemTime) * 1000.0), Helper::humanReadableBytes($memoryUsage), Helper::humanReadableBytes(memory_get_peak_usage(true)), $sqlQueries !== null ? $sqlQueries : 'n/a');
     // Remove values to prevent caching
     $extras = $event->getExtras();
     unset($extras['module_profiler.time']);
     unset($extras['module_profiler.query_count']);
     unset($extras['module_profiler.user_time']);
     unset($extras['module_profiler.system_time']);
     unset($extras['module_profiler.memory_usage']);
     $event->setExtras($extras);
 }
예제 #2
0
 public static function setUpBeforeClass()
 {
     parent::setUpBeforeClass();
     self::$fixturesDirectory = realpath(dirname(dirname(__DIR__)) . '/fixtures');
     $app = App::create(array('name' => 'Curry Unit Tests', 'adminEmail' => '*****@*****.**', 'cache' => array('method' => 'none'), 'pageCache' => false, 'autoBackup' => false, 'projectPath' => self::$fixturesDirectory, 'migrationVersion' => App::MIGRATION_VERSION, 'template' => array('root' => self::$fixturesDirectory . '/templates', 'options' => array('cache' => false)), 'propel' => array('conf' => self::$fixturesDirectory . '/propel/build/conf/curry-conf.php', 'projectClassPath' => self::$fixturesDirectory . '/propel/build/classes')));
     $app->boot();
     // Empty database
     $con = \Propel::getConnection();
     $con->beginTransaction();
     try {
         foreach (\Curry\Util\Propel::getModels(false) as $model) {
             \PropelQuery::from($model)->deleteAll();
         }
         $con->commit();
     } catch (\Exception $e) {
         $con->rollBack();
         throw $e;
     }
     $setup = new \Curry\Backend\Setup($app);
     $setup->saveConfiguration(array('admin' => array('username' => 'admin', 'password' => 'admin')));
     $app->cache->clean();
 }
예제 #3
0
 /**
  * Should be called before calling doRebuild().
  */
 public static function initRebuild()
 {
     $models = array();
     foreach (Propel::getModels() as $classes) {
         foreach ($classes as $model) {
             if (in_array('Curry_ISearchable', class_implements($model))) {
                 $models[] = $model;
             }
         }
     }
     if (\Curry\App::getInstance()['indexerClass']) {
         $models[] = '@custom';
     }
     $ses = new \Zend\Session\Container(__CLASS__);
     $ses->models = $models;
     $ses->model = 0;
     $ses->offset = 0;
     $ses->limit = 10;
     $ses->failed = 0;
     $ses->success = 0;
 }
예제 #4
0
 /**
  * Restore database from file.
  * 
  * @todo Fix $maxExecutionTime.
  *
  * @param string|resource $file
  * @param array|null $tables
  * @param float $maxExecutionTime
  * @param int $continueLine
  * @param AbstractLegacyBackend|null $backend
  * @return bool	True on success, false otherwise.
  */
 public static function restoreFromFile($file, $tables = null, $maxExecutionTime = 0, $continueLine = 0, AbstractLegacyBackend $backend = null)
 {
     global $CURRY_DATABASE_RESTORE;
     $CURRY_DATABASE_RESTORE = true;
     $fp = is_string($file) ? fopen($file, "r") : $file;
     $t = microtime(true);
     $total = 0;
     $skipped = 0;
     $failed = 0;
     $session = new \Zend\Session\Container(__CLASS__);
     $con = Propel::getConnection();
     $con->beginTransaction();
     $adapter = Propel::getDB();
     if ($adapter instanceof DBMySQL) {
         $con->exec("SET foreign_key_checks = 0");
     }
     // Read header
     $firstline = stream_get_line($fp, self::MAX_LINE_LENGTH, "\n");
     $header = json_decode($firstline, true);
     if (is_array($header) && isset($header['header'])) {
         $header = $header['header'];
         // Check header version
         $version = isset($header['version']) ? (int) $header['version'] : 0;
         if ($version > self::VERSION) {
             throw new Exception('Unsupported database version. The file you are trying to restore from is from a newer version of currycms.');
         }
         // Check page version
         $pageVersion = isset($header['page-version']) ? (int) $header['page-version'] : 0;
         if ($pageVersion > Page::VERSION) {
             throw new Exception('Unsupported page version. The file you are trying to restore from is from a newer version of currycms.');
         }
         if ($backend) {
             $backend->addMessage("Restoring from " . $header['date']);
         }
         if ($pageVersion !== Page::VERSION) {
             if ($backend) {
                 $backend->addMessage("Migrating data from version {$pageVersion} to " . Page::VERSION, AbstractBackend::MSG_WARNING);
             }
             Page::preMigrate($pageVersion);
         }
     } else {
         throw new Exception('Invalid header');
     }
     // Empty tables
     if ($continueLine == 0) {
         foreach (Propel::getModels() as $classes) {
             foreach ($classes as $table) {
                 try {
                     if (is_array($tables) && !in_array($table, $tables)) {
                         continue;
                     }
                     if (!method_exists($table, 'delete')) {
                         if ($backend) {
                             $backend->addMessage("Skipping read-only table: {$table}", AbstractBackend::MSG_WARNING);
                         }
                         continue;
                     }
                     $tableName = PropelQuery::from($table)->getTableMap()->getName();
                     // use basePeer to avoid foreign key emulation in Normal peer class
                     BasePeer::doDeleteAll($tableName, $con);
                 } catch (Exception $e) {
                     throw new Exception('Unable to empty table ' . $table . ': ' . $e->getMessage());
                 }
             }
         }
         if ($backend) {
             $backend->addMessage("Cleared tables in " . round(microtime(true) - $t, 2) . "s");
         }
         $t = microtime(true);
     } else {
         $total = $session->total;
         $skipped = $session->skipped;
         $failed = $session->failed;
         if ($backend) {
             $backend->addMessage("Continuing from line {$continueLine}.");
         }
         for ($i = 0; $i < $continueLine; ++$i) {
             stream_get_line($fp, self::MAX_LINE_LENGTH, "\n");
         }
     }
     $currentTable = null;
     $buffer = array();
     while (!feof($fp)) {
         // Read line
         $data = json_decode(stream_get_line($fp, self::MAX_LINE_LENGTH, "\n"), true);
         ++$total;
         if (is_array($data) && isset($data['table'])) {
             if (is_array($tables) && !in_array($data['table'], $tables) || !method_exists($data['table'], 'delete')) {
                 ++$skipped;
                 continue;
             }
             // Verify columns for new table
             if ($data['table'] !== $currentTable && $currentTable !== null && $backend) {
                 $backend->addMessage('Restoring rows for table ' . $data['table']);
                 $columns = ArrayHelper::objectsToArray(PropelQuery::from($data['table'])->getTableMap()->getColumns(), null, 'getPhpName');
                 $added = array_diff($columns, array_keys($data['values']));
                 $removed = array_diff(array_keys($data['values']), $columns);
                 if (count($added)) {
                     $backend->addMessage('New column(s): ' . join(', ', $added), AbstractBackend::MSG_WARNING);
                 }
                 if (count($removed)) {
                     $backend->addMessage('Removed column(s): ' . join(', ', $removed), AbstractBackend::MSG_WARNING);
                 }
             }
             // Flush buffer when changing tables
             if ($data['table'] !== $currentTable || count($buffer) >= self::MULTIINSERT_MAXBUFFER) {
                 if ($currentTable !== null && count($buffer)) {
                     Propel::doMultiInsert($currentTable, $buffer);
                 }
                 $currentTable = $data['table'];
                 $buffer = array();
             }
             // Migrate data
             if ($pageVersion !== Page::VERSION) {
                 if (!Page::migrateData($data['table'], $data['values'], $pageVersion)) {
                     continue;
                 }
             }
             $buffer[] = $data['values'];
         } else {
             if ($backend) {
                 $backend->addMessage('Unable to read data on line ' . $total, AbstractBackend::MSG_ERROR);
             }
             ++$failed;
         }
         // check execution time
         if ($maxExecutionTime && App::getInstance()->getExecutionTime() > $maxExecutionTime) {
             if ($currentTable !== null && count($buffer)) {
                 Propel::doMultiInsert($currentTable, $buffer);
             }
             $session->total = $total;
             $session->skipped = $skipped;
             $session->failed = $failed;
             $params = array('module' => 'Curry_Backend_Database', 'view' => 'ContinueRestore', 'file' => $file, 'tables' => $tables, 'line' => $total, 'max_execution_time' => $maxExecutionTime);
             AbstractLegacyBackend::redirect(url('', $params)->getAbsolute("&", true));
         }
     }
     // Flush buffer
     if ($currentTable !== null && count($buffer)) {
         Propel::doMultiInsert($currentTable, $buffer);
     }
     if ($pageVersion !== Page::VERSION) {
         Page::postMigrate($pageVersion);
     }
     if ($adapter instanceof DBMySQL) {
         $con->exec("SET foreign_key_checks = 1");
     }
     $con->commit();
     $CURRY_DATABASE_RESTORE = false;
     if ($backend) {
         if ($skipped) {
             $backend->addMessage("Skipped {$skipped} rows");
         }
         if ($failed) {
             $backend->addMessage("Failed to add {$failed} rows", AbstractBackend::MSG_ERROR);
         }
         $backend->addMessage("Added " . ($total - $skipped - $failed) . " / {$total} rows in " . round(microtime(true) - $t, 2) . "s", !$failed ? AbstractBackend::MSG_SUCCESS : AbstractBackend::MSG_ERROR);
     }
     if (is_string($file)) {
         fclose($fp);
     }
     return !$failed;
 }
예제 #5
0
 public function sortItems($params)
 {
     ModuleSortorderQuery::create()->filterByPageRevision($this->pageRevision)->delete();
     $wrappers = $this->pageRevision->getPageModuleWrappers();
     $unsortedIds = ArrayHelper::objectsToArray($wrappers, false, 'getPageModuleId');
     $wrapperById = ArrayHelper::objectsToArray($wrappers, 'getPageModuleId');
     // Get primary keys
     $items = $_POST['item'];
     if (!is_array($items)) {
         throw new Exception('Expected array POST variable `item`.');
     }
     $sortedIds = array();
     foreach ($items as $item) {
         $pk = json_decode($item, true);
         if ($pk === null) {
             throw new Exception('Invalid primary key for item: ' . $item);
         }
         if (!array_key_exists($pk, $wrapperById)) {
             throw new Exception('Module not found when sorting');
         }
         $sortedIds[] = $pk;
     }
     if ($sortedIds !== $unsortedIds) {
         foreach ($wrappers as $wrapper) {
             $sortorder = $wrapper->getSortorder(true);
             $sortorder->insertAtBottom();
             $sortorder->save();
         }
         $pks = array();
         foreach ($sortedIds as $id) {
             $pks[] = array($id, $this->pageRevision->getPageRevisionId());
         }
         Propel::sortableReorder($pks, 'ModuleSortorder');
     }
     $this->pageRevision->setUpdatedAt(time());
     $this->pageRevision->save();
 }
예제 #6
0
 /**
  * {@inheritdoc}
  */
 public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
 {
     $startTime = microtime(true);
     $this->logger->debug(($type === HttpKernelInterface::MASTER_REQUEST ? 'Master-Request: ' : 'Sub-Request') . $request->getMethod() . ' ' . $request->getRequestUri());
     $previous = isset($this->request) ? $this->request : null;
     $this->request = $request;
     $response = $this->kernel->handle($request, $type, $catch);
     $this->request = $previous;
     if ($this['developmentMode']) {
         $queryCount = Util\Propel::getQueryCount();
         $this->logger->debug("Response completed", array('time' => microtime(true) - $startTime, 'mem' => Helper::humanReadableBytes(memory_get_peak_usage()), 'sql' => $queryCount !== null ? $queryCount : 'n/a'));
     }
     return $response;
 }
예제 #7
0
 /**
  * Override formatter function for one item.
  *
  * @param PDOStatement $stmt
  * @return mixed
  */
 public function formatOne(PDOStatement $stmt)
 {
     $item = parent::format($stmt);
     if ($this->formatterFunction) {
         return call_user_func($this->formatterFunction, $item);
     }
     if (is_object($item) && $item instanceof BaseObject) {
         return Propel::toTwig($item);
     }
     return $item;
 }
예제 #8
0
 public function templateToString($template, \BaseObject $obj)
 {
     $tpl = $this->app->loadTemplateString($template);
     return $tpl->render(Propel::toTwig($obj));
 }
예제 #9
0
 /**
  * Restore database.
  */
 public function showRestore()
 {
     $this->showMainMenu();
     $tables = array();
     $selectedTables = array();
     $disabledTables = array();
     foreach (Propel::getModels() as $package => $classes) {
         $tables[$package] = array();
         foreach ($classes as $table) {
             $tables[$package][$table] = $table;
             if (method_exists($table, 'save')) {
                 $selectedTables[] = $table;
             } else {
                 $disabledTables[] = $table;
             }
         }
     }
     $files = array('' => '-- Select file --', 'upload' => '[ Upload from computer ]', 'remote' => '[ From remote server ]');
     $path = Curry_Backend_DatabaseHelper::createBackupName('*.txt');
     foreach (array_reverse(glob($path)) as $file) {
         $files[$file] = basename($file) . ' (' . Helper::humanReadableBytes(filesize($file)) . ')';
     }
     $form = new Curry_Form(array('action' => url('', array("module", "view", "page_id")), 'method' => 'post', 'enctype' => 'multipart/form-data', 'elements' => array('tables' => array('multiselect', array('label' => 'Tables', 'multiOptions' => $tables, 'value' => $selectedTables, 'disable' => $disabledTables, 'size' => 15)), 'file' => array('select', array('label' => 'From file', 'multiOptions' => $files, 'class' => 'trigger-change', 'onchange' => "\$('#uploadfile-label').next().andSelf()[this.value == 'upload'?'show':'hide']();" . "\$('#remote-label').next().andSelf()[this.value == 'remote'?'show':'hide']();")), 'uploadfile' => array('file', array('label' => 'Upload file', 'valueDisabled' => true)), 'remote' => array('text', array('label' => 'Remote')), 'max_execution_time' => array('text', array('label' => 'Max execution time', 'value' => '', 'description' => 'Input time in seconds to allow interruption if the time taken to restore would exceed the maximum execution time.')))));
     $form->addElement('submit', 'Go');
     if (isPost() && $form->isValid($_POST)) {
         if ($form->file->getValue() == 'upload') {
             if (!$form->uploadfile->isUploaded()) {
                 throw new Exception('No file was uploaded.');
             }
             $fileinfo = $form->uploadfile->getFileInfo();
             Curry_Backend_DatabaseHelper::restoreFromFile($fileinfo['uploadfile']['tmp_name'], $form->tables->getValue(), 0, 0, $this);
         } else {
             if ($form->file->getValue() == 'remote') {
                 if (!$form->remote->getValue()) {
                     throw new Exception('No remote URL set');
                 }
                 $url = url($form->remote->getValue());
                 $post = array('login_username' => $url->getUser(), 'login_password' => $url->getPassword(), 'tables' => '*', 'name' => 'db.txt', 'type' => 'local');
                 $url->setUser(null)->setPassword(null)->setPath('/admin.php')->add(array('module' => 'Curry_Backend_Database', 'view' => 'Backup'));
                 $context = stream_context_create(array('http' => array('method' => 'POST', 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 'content' => http_build_query($post))));
                 $fp = fopen($url, 'r', false, $context);
                 Curry_Backend_DatabaseHelper::restoreFromFile($fp, $form->tables->getValue(), 0, 0, $this);
                 fclose($fp);
             } else {
                 if ($form->file->getValue()) {
                     Curry_Backend_DatabaseHelper::restoreFromFile($form->file->getValue(), $form->tables->getValue(), (int) $form->max_execution_time->getValue(), 0, $this);
                 }
             }
         }
     }
     $this->addMainContent($form);
 }