/** * Pass methods along to Garp_Content_Manager. * @param String $model The desired model to manipulate * @param String $method The desired method to execute * @param Array $args Arguments * @return Mixed Whatever the Garp_Content_Manager returns, optionally converted to array. */ public function pass($model, $method, $args = array()) { $manager = new Garp_Content_Manager(Garp_Content_Api::modelAliasToClass($model)); if (!method_exists($manager, $method)) { throw new Garp_Content_Exception('Unknown method requested.'); } $params = !empty($args) ? $args[0] : array(); $result = $this->_produceResult($manager, $method, $params); if ($result instanceof Zend_Db_Table_Rowset_Abstract || $result instanceof Zend_Db_Table_Row_Abstract) { $result = $result->toArray(); } return $result; }
/** * Walks over every text column of every record of every table * and replaces references to $subject with $replacement. * Especially useful since all images in Rich Text Editors are * referenced with absolute paths including the domain. This method * can be used to replace "old domain" with "new domain" in one go. * * @param array $args * @return bool */ public function replace(array $args = array()) { $subject = !empty($args[0]) ? $args[0] : Garp_Cli::prompt('What is the string you wish to replace?'); $replacement = !empty($args[1]) ? $args[1] : Garp_Cli::prompt('What is the new string you wish to insert?'); $subject = trim($subject); $replacement = trim($replacement); $models = Garp_Content_Api::getAllModels(); foreach ($models as $model) { if (is_subclass_of($model->class, 'Garp_Model_Db')) { $this->_replaceString($model->class, $subject, $replacement); } } return true; }
/** * Return the API layout, e.g. which methods may be called on which entities. * @return stdClass */ public function getLayout() { $methods = array('fetch' => array('fetch', 'fetch_own'), 'create', 'update' => array('update', 'update_own'), 'destroy' => array('destroy', 'destroy_own'), 'count' => array('fetch'), 'relate'); $auth = Garp_Auth::getInstance(); if (is_null($this->_layout)) { // read content managing configuration from content.ini // note; Garp_Cache_Config is not used here because we always want fresh data in the CMS, // no cached versions $config = Garp_Content_Api::_getConfig(); $classes = $config->content->commands; $api = new stdClass(); $api->actions = array(); foreach ($classes as $key => $class) { $alias = !empty($class->alias) ? $class->alias : $key; $modelName = self::modelAliasToClass($alias); if (!array_key_exists($alias, $api->actions)) { $api->actions[$alias] = array(); } foreach ($methods as $method => $privileges) { if (is_numeric($method)) { $method = $privileges; $privileges = array($method); } // Check if any of the given privileges allow for the method to be executed $allowed = false; foreach ($privileges as $privilege) { if ($auth->isAllowed($modelName, $privilege)) { $allowed = true; break; } } // If the method is not allowed, don't mention it in the SMD if (!$allowed) { continue; } $api->actions[$alias][] = array('name' => $method, 'len' => 1); } } $this->_layout = $api; } return $this->_layout; }
/** * Modify results after update * * @param Array $response The original response * @param Array $request The original request * @return String */ protected function _modifyAfterUpdate($response, $request) { if ($this->_methodFailed($response)) { return $response; } $methodParts = explode('.', $request['method']); $modelClass = Garp_Content_Api::modelAliasToClass(array_shift($methodParts)); $man = new Garp_Content_Manager($modelClass); $rows = $man->fetch(array('query' => array('id' => $request['params'][0]['rows']['id']))); $response['result'] = array('rows' => $rows); return $response; }
/** * Import content from various formats. * This action has two states; * - first a datafile is uploaded. The user is presented with a mapping interface * where they have to map columns in the datafile to columns in the database. * - then this URL is called again with the selected mapping, and the columns are * mapped and inserted into the database. * * @return Void */ public function importAction() { $memLim = ini_get('memory_limit'); ini_set('memory_limit', '2G'); set_time_limit(0); // No time limit Zend_Registry::set('CMS', true); $params = new Garp_Util_Configuration($this->getRequest()->getParams()); $params->obligate('datafile')->obligate('model')->setDefault('firstRow', 0)->setDefault('ignoreErrors', false); $importer = Garp_Content_Import_Factory::getImporter($params['datafile']); $success = false; if (isset($params['mapping'])) { $mapping = Zend_Json::decode($params['mapping']); $className = Garp_Content_Api::modelAliasToClass($params['model']); $model = new $className(); $response = array(); try { $success = !!$importer->save($model, $mapping, array('firstRow' => $params['firstRow'], 'ignoreErrors' => $params['ignoreErrors'])); } catch (Exception $e) { $response['message'] = $e->getMessage(); } if ($success) { // cleanup input file $gf = new Garp_File(); $gf->remove($params['datafile']); } $response['success'] = $success; $this->view->response = $response; } else { $std = new stdClass(); $std->success = true; $std->data = $importer->getSampleData(); $this->view->response = $std; } ini_set('memory_limit', $memLim); $this->_helper->layout->setLayout('json'); $this->renderScript('content/call.phtml'); }
/** * Generate a filename for the exported text file * * @param Garp_Util_Configuration $params * @return string */ public function getFilename(Garp_Util_Configuration $params) { $className = Garp_Content_Api::modelAliasToClass($params['model']); $model = new $className(); $filename = 'export_'; $filename .= $model->getName(); $filename .= '_' . date('Y_m_d'); $filename .= '.'; $filename .= $this->_extension; return $filename; }
/** * Add a JOIN clause to a Zend_Db_Select object * * @param Zend_Db_Select $select The select object * @param array $related Collection of related models * @param string $rule Used to figure out the relationship metadata from the referencemap * @param string $bindingModel Binding model used in HABTM relations * @param bool $bidirectional * @return void */ protected function _addJoinClause(Zend_Db_Select $select, array $related, $rule = null, $bindingModel = null, $bidirectional = true) { foreach ($related as $filterModelName => $filterValue) { $fieldInfo = explode('.', $filterModelName, 2); $filterModelName = Garp_Content_Api::modelAliasToClass($fieldInfo[0]); $filterColumn = $fieldInfo[1]; $filterModel = new $filterModelName(); /** * Determine wether a negation clause (e.g. !=) is requested * and normalize the filterColumn. */ $negation = strpos($filterColumn, '<>') !== false; $filterColumn = str_replace(' <>', '', $filterColumn); if ($filterModelName === get_class($this->_model)) { /* This is a homophile relation and the current condition touches the homophile model. The following condition prevents a 'relatable' list to include the current record, because a record cannot be related to itself. */ $select->where($this->_getTableName($filterModel) . '.' . $filterColumn . ' != ?', $filterValue); } try { // the other model is a child $reference = $filterModel->getReference(get_class($this->_model), $rule); $this->_addHasManyClause(array('select' => $select, 'filterModel' => $filterModel, 'reference' => $reference, 'filterColumn' => $filterColumn, 'filterValue' => $filterValue, 'negation' => $negation)); } catch (Zend_Db_Table_Exception $e) { try { // the other model is the parent $reference = $this->_model->getReference(get_class($filterModel), $rule); $this->_addBelongsToClause(array('select' => $select, 'reference' => $reference, 'filterColumn' => $filterColumn, 'filterValue' => $filterValue, 'negation' => $negation)); } catch (Zend_Db_Table_Exception $e) { try { // the models are equal; a binding model is needed $this->_addHasAndBelongsToManyClause(array('select' => $select, 'filterModel' => $filterModel, 'filterColumn' => $filterColumn, 'filterValue' => $filterValue, 'negation' => $negation, 'bindingModel' => $bindingModel, 'bidirectional' => $bidirectional)); } catch (Zend_Db_Table_Exception $e) { throw $e; } } } } }