/**
  * Returns the alternate view template paths (a.k.a. template overrides in Joomla!-speak) for the given View name
  *
  * @param string $viewName The name of the view triggering this event
  *
  * @return array The template override paths
  */
 public function onGetViewTemplatePaths($viewName)
 {
     $container = $this->subject->getContainer();
     $application_name = $container->application_name;
     $component_name = 'com_' . strtolower($application_name);
     // That's the path in the site's current template containing template overrides
     $overridePath = Helper::getTemplateOverridePath($component_name, true);
     // The alternative view name (pluralised if the view is singular, singularised if the view is plural)
     $altViewName = Inflector::isPlural($viewName) ? Inflector::singularize($viewName) : Inflector::pluralize($viewName);
     // Remember, each path is pushed to the TOP of the path stack. This means that the least important directory
     // must go FIRST so that it ends add being added LAST.
     return array($overridePath . '/' . $altViewName, $overridePath . '/' . $viewName);
 }
Exemple #2
0
 /**
  * Returns a new model object. Unless overridden by the $config array, it will
  * try to automatically populate its state from the request variables.
  *
  * By default the new model instance is created with persistent state, unless
  * you pass $config['modelTemporaryInstance'] = false
  *
  * @param   string    $appName   The application name
  * @param   string    $modelName The model name
  * @param   Container $container Configuration variables to the model
  *
  * @return  static
  *
  * @throws  \RuntimeException  If the Model is not found
  */
 public static function getInstance($appName = null, $modelName = '', $container = null)
 {
     if (empty($appName) && !is_object($container)) {
         $app = Application::getInstance();
         $appName = $app->getName();
         $container = $app->getContainer();
     } elseif (empty($appName) && is_object($container)) {
         $appName = $container->application_name;
     } elseif (!empty($appName) && !is_object($container)) {
         $container = Application::getInstance($appName)->getContainer();
     }
     $config = isset($container['mvc_config']) ? $container['mvc_config'] : array();
     if (empty($modelName)) {
         $modelName = $container->input->getCmd('view', '');
     }
     // Try to load the Model class
     $classes = array('\\' . ucfirst($appName) . '\\Model\\' . ucfirst($modelName), '\\' . ucfirst($appName) . '\\Model\\' . ucfirst(Inflector::pluralize($modelName)), '\\' . ucfirst($appName) . '\\Model\\DefaultModel');
     foreach ($classes as $className) {
         if (class_exists($className)) {
             break;
         }
     }
     if (!class_exists($className)) {
         throw new \RuntimeException("Model not found (app : model) = {$appName} : {$modelName}");
     }
     /** @var Model $result */
     $result = new $className($container);
     if (array_key_exists('modelTemporaryInstance', $config) && $config['modelTemporaryInstance']) {
         $result = $result->getClone()->savestate(0);
     }
     if (array_key_exists('modelClearState', $config) && $config['modelClearState']) {
         $result->clearState();
     }
     if (array_key_exists('modelClearInput', $config) && $config['modelClearInput']) {
         $result->clearInput();
     }
     return $result;
 }
Exemple #3
0
 /**
  * Creates an instance of a controller object.
  *
  * @param   string    $appName    The application name [optional] Default: the default application
  * @param   string    $controller The controller name [optional] Default: based on the "view" input parameter
  * @param   Container $container  The DI container [optional] Default: the application container of the $appName application
  *
  * @return  Controller  A Controller instance
  *
  * @throws  \RuntimeException  When you are referring to a controller class which doesn't exist
  */
 public static function &getInstance($appName = null, $controller = null, $container = null)
 {
     if (empty($appName) && !is_object($container)) {
         $app = Application::getInstance();
         $appName = $app->getName();
         $container = $app->getContainer();
     } elseif (empty($appName) && is_object($container)) {
         $appName = $container->application_name;
     } elseif (!empty($appName) && !is_object($container)) {
         $container = Application::getInstance($appName)->getContainer();
     }
     $input = $container->input;
     if (empty($controller)) {
         $controller = $input->getCmd('view', '');
     }
     // Get the class base name, e.g. \Foobar\Controller\
     $classBaseName = '\\' . ucfirst($appName) . '\\Controller\\';
     // Get the class name suffixes, in the order to be searched for
     $classSuffixes = array($controller, Inflector::singularize($controller), Inflector::pluralize($controller), 'DefaultController');
     // Look for the best classname match
     foreach ($classSuffixes as $suffix) {
         $className = $classBaseName . ucfirst($suffix);
         if (class_exists($className)) {
             // The class is loaded. We have a match!
             break;
         }
     }
     if (!class_exists($className)) {
         throw new \RuntimeException("Controller not found (app : controller) = {$appName} : {$controller}");
     }
     $instance = new $className($container);
     return $instance;
 }
Exemple #4
0
 /**
  * Public constructor. Overrides the parent constructor, adding support for database-aware models.
  *
  * You can use the $container['mvc_config'] array to pass some configuration values to the object:
  *
  * tableName            String. The name of the database table to use. Default: #__appName_viewNamePlural (Ruby on Rails convention)
  * idFieldName            String. The table key field name. Default: appName_viewNameSingular_id (Ruby on Rails convention)
  * knownFields            Array. The known fields in the table. Default: read from the table itself
  * autoChecks            Boolean. Should I turn on automatic data validation checks?
  * fieldsSkipChecks        Array. List of fields which should not participate in automatic data validation checks.
  * aliasFields            Array. Associative array of "magic" field aliases.
  * behavioursDispatcher    EventDispatcher. The model behaviours event dispatcher.
  * behaviourObservers    Array. The model behaviour observers to attach to the behavioursDispatcher.
  * behaviours            Array. A list of behaviour names to instantiate and attach to the behavioursDispatcher.
  * fillable_fields        Array. Which fields should be auto-filled from the model state (by extent, the request)?
  * guarded_fields        Array. Which fields should never be auto-filled from the model state (by extent, the request)?
  * relations            Array (hashed). The relations to autoload on model creation.
  *
  * Setting either fillable_fields or guarded_fields turns on automatic filling of fields in the constructor. If both
  * are set only guarded_fields is taken into account. Fields are not filled automatically outside the constructor.
  *
  * @see \Awf\Mvc\Model::__construct()
  *
  * @param   Container $container
  */
 public function __construct(\Awf\Container\Container $container = null)
 {
     if (!is_object($container)) {
         $container = Application::getInstance()->getContainer();
     }
     // First call the parent constructor. It also populates $this->config from $container['mvc_config']
     parent::__construct($container);
     // Should I use a different database object?
     $this->dbo = $container->db;
     // Do I have a table name?
     if (isset($this->config['tableName'])) {
         $this->tableName = $this->config['tableName'];
     } elseif (empty($this->tableName)) {
         // The table name is by default: #__appName_viewNamePlural (Ruby on Rails convention)
         $viewPlural = Inflector::pluralize($this->getName());
         $this->tableName = '#__' . strtolower($this->container->application->getName()) . '_' . strtolower($viewPlural);
     }
     // Do I have a table key name?
     if (isset($this->config['idFieldName'])) {
         $this->idFieldName = $this->config['idFieldName'];
     } elseif (empty($this->idFieldName)) {
         // The default ID field is: appName_viewNameSingular_id (Ruby on Rails convention)
         $viewSingular = Inflector::singularize($this->getName());
         $this->idFieldName = strtolower($this->container->application->getName()) . '_' . strtolower($viewSingular) . '_id';
     }
     // Do I have a list of known fields?
     if (isset($this->config['knownFields'])) {
         $this->knownFields = $this->config['knownFields'];
     } else {
         // By default the known fields are fetched from the table itself (slow!)
         $this->knownFields = $this->getTableFields();
     }
     if (empty($this->knownFields)) {
         throw new NoTableColumns(sprintf('Model %s could not fetch column list for the table %s', $this->getName(), $this->tableName));
     }
     // Should I turn on autoChecks?
     if (isset($this->config['autoChecks'])) {
         $this->autoChecks = $this->config['autoChecks'];
     }
     // Should I exempt fields from autoChecks?
     if (isset($this->config['fieldsSkipChecks'])) {
         $this->fieldsSkipChecks = $this->config['fieldsSkipChecks'];
     }
     // Do I have alias fields?
     if (isset($this->config['aliasFields'])) {
         $this->aliasFields = $this->config['aliasFields'];
     }
     // Do I have a behaviours dispatcher?
     if (isset($this->config['behavioursDispatcher']) && $this->config['behavioursDispatcher'] instanceof EventDispatcher) {
         $this->behavioursDispatcher = $this->config['behavioursDispatcher'];
     } else {
         $this->behavioursDispatcher = new EventDispatcher($this->container);
     }
     // Do I have an array of behaviour observers
     if (isset($this->config['behaviourObservers']) && is_array($this->config['behaviourObservers'])) {
         foreach ($this->config['behaviourObservers'] as $observer) {
             $this->behavioursDispatcher->attach($observer);
         }
     }
     // Do I have a list of behaviours?
     if (isset($this->config['behaviours']) && is_array($this->config['behaviours'])) {
         foreach ($this->config['behaviours'] as $behaviour) {
             $this->addBehaviour($behaviour);
         }
     }
     // Do I have a list of fillable fields?
     if (isset($this->config['fillable_fields']) && is_array($this->config['fillable_fields'])) {
         $this->fillable = array();
         $this->autoFill = true;
         foreach ($this->config['fillable_fields'] as $field) {
             if (array_key_exists($field, $this->knownFields)) {
                 $this->fillable[] = $field;
             } elseif (isset($this->aliasFields[$field])) {
                 $this->fillable[] = $this->aliasFields[$field];
             }
         }
     }
     // Do I have a list of guarded fields?
     if (isset($this->config['guarded_fields']) && is_array($this->config['guarded_fields'])) {
         $this->guarded = array();
         $this->autoFill = true;
         foreach ($this->config['guarded_fields'] as $field) {
             if (array_key_exists($field, $this->knownFields)) {
                 $this->guarded[] = $field;
             } elseif (isset($this->aliasFields[$field])) {
                 $this->guarded[] = $this->aliasFields[$field];
             }
         }
     }
     // Do I have to auto-fill the fields?
     if ($this->autoFill) {
         // If I have guarded fields, I'll try to fill everything, using such fields as a "blacklist"
         if (!empty($this->guarded)) {
             $fields = array_keys($this->knownFields);
         } else {
             // Otherwise I'll fill only the fillable ones (act like having a "whitelist")
             $fields = $this->fillable;
         }
         foreach ($fields as $field) {
             if (in_array($field, $this->guarded)) {
                 // Do not set guarded fields
                 continue;
             }
             $stateValue = $this->getState($field, null);
             if (!is_null($stateValue)) {
                 $this->setFieldValue($field, $stateValue);
             }
         }
     }
     // Create a relation manager
     $this->relationManager = new RelationManager($this);
     // Do I have a list of relations?
     if (isset($this->config['relations']) && is_array($this->config['relations'])) {
         foreach ($this->config['relations'] as $name => $relConfig) {
             if (!is_array($relConfig)) {
                 continue;
             }
             $defaultRelConfig = array('type' => 'hasOne', 'foreignModelClass' => null, 'localKey' => null, 'foreignKey' => null, 'pivotTable' => null, 'pivotLocalKey' => null, 'pivotForeignKey' => null);
             $relConfig = array_merge($defaultRelConfig, $relConfig);
             $this->relationManager->addRelation($name, $relConfig['type'], $relConfig['foreignModelClass'], $relConfig['localKey'], $relConfig['foreignKey'], $relConfig['pivotTable'], $relConfig['pivotLocalKey'], $relConfig['pivotForeignKey']);
         }
     }
     // Initialise the data model
     foreach ($this->knownFields as $fieldName => $information) {
         // Initialize only the null or not yet set records
         if (!isset($this->recordData[$fieldName])) {
             $this->recordData[$fieldName] = $information->Default;
         }
     }
 }
Exemple #5
0
 /**
  * Adds a relation to the relation manager
  *
  * @param   string $name               The name of the relation as known to this relation manager, e.g. 'phone'
  * @param   string $type               The relation type, e.g. 'hasOne'
  * @param   string $foreignModelClass  The class name of the foreign key's model, e.g. '\Foobar\Phones'
  * @param   string $localKey           The local table key for this relation
  * @param   string $foreignKey         The foreign key for this relation
  * @param   string $pivotTable         For many-to-many relations, the pivot (glue) table
  * @param   string $pivotLocalKey      For many-to-many relations, the pivot table's column storing the local key
  * @param   string $pivotForeignKey    For many-to-many relations, the pivot table's column storing the foreign key
  *
  * @return DataModel The parent model, for chaining
  *
  * @throws Relation\Exception\RelationTypeNotFound when $type is not known
  * @throws Relation\Exception\ForeignModelNotFound when $foreignModelClass doesn't exist
  */
 public function addRelation($name, $type, $foreignModelClass = null, $localKey = null, $foreignKey = null, $pivotTable = null, $pivotLocalKey = null, $pivotForeignKey = null)
 {
     if (!isset(static::$relationTypes[$type])) {
         throw new DataModel\Relation\Exception\RelationTypeNotFound("Relation type '{$type}' not found");
     }
     // Guess the foreign model class if necessary
     if (empty($foreignModelClass) || !class_exists($foreignModelClass, true)) {
         $parentClass = get_class($this->parentModel);
         $classNameParts = explode('\\', $parentClass);
         array_pop($classNameParts);
         $classPrefix = implode('\\', $classNameParts);
         $foreignModelClass = $classPrefix . '\\' . ucfirst($name);
         if (!class_exists($foreignModelClass, true)) {
             $foreignModelClass = $classPrefix . '\\' . ucfirst(Inflector::pluralize($name));
         }
     }
     if (!class_exists($foreignModelClass, true)) {
         throw new DataModel\Relation\Exception\ForeignModelNotFound("Foreign model '{$foreignModelClass}' for relation '{$name}' not found");
     }
     $className = static::$relationTypes[$type];
     /** @var Relation $relation */
     $relation = new $className($this->parentModel, $foreignModelClass, $localKey, $foreignKey, $pivotTable, $pivotLocalKey, $pivotForeignKey);
     $this->relations[$name] = $relation;
     return $this->parentModel;
 }
Exemple #6
0
 /**
  * Delete selected item(s)
  *
  * @return  void
  */
 public function remove()
 {
     // CSRF prevention
     $this->csrfProtection();
     $model = $this->getModel();
     $ids = $this->getIDsFromRequest($model, false);
     try {
         $status = true;
         foreach ($ids as $id) {
             $model->find($id);
             $model->delete();
         }
     } catch (\Exception $e) {
         $status = false;
         $error = $e->getMessage();
     }
     // Redirect
     if ($customURL = $this->input->getBase64('returnurl', '')) {
         $customURL = base64_decode($customURL);
     }
     $router = $this->container->router;
     $url = !empty($customURL) ? $customURL : $router->route('index.php?view=' . Inflector::pluralize($this->view));
     if (!$status) {
         $this->setRedirect($url, $error, 'error');
     } else {
         $textKey = $this->container->application_name . '_LBL_' . Inflector::singularize($this->view) . '_DELETED';
         $this->setRedirect($url, Text::_($textKey));
     }
 }