Example #1
0
 /**
  * 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);
 }
Example #2
0
 /**
  * Checks if the current user has enough privileges for the requested ACL
  * area.
  *
  * @param string $area The ACL area, e.g. core.manage.
  *
  * @return bool True if the user has the ACL privilege specified
  */
 protected function checkACL($controller_name, $area)
 {
     // If the area is one of false, 0, no or 403 we cancel the action
     if (in_array(strtolower($area), array('false', '0', 'no', '403'))) {
         return false;
     }
     // If the area is one of true, 1, yes we proceed with the action
     if (in_array(strtolower($area), array('true', '1', 'yes'))) {
         return true;
     }
     // If no ACL area is specified we proceed with the action
     if (empty($area)) {
         return true;
     }
     // Get the controller, model and table
     $container = $this->subject->getContainer();
     $application_name = $container->application_name;
     $component_name = 'com_' . strtolower($application_name);
     /** @var DataController $controller */
     $controller = Controller::getInstance($application_name, $controller_name, $container);
     $model = $controller->getModel();
     // If it's not a data model or it's not assets tracked just perform a regular ACL check on the component
     if (!$model instanceof DataModel || !$model->getState('_isAssetsTracked', false)) {
         return Helper::authorise($area, $component_name);
     }
     // Initialise
     $ids = null;
     // Get the IDs in the request
     $ids = $controller->getIDsFromRequest($model, false);
     // If there are no IDs there is no asset tracking, fall back to the generic ACL check
     if (empty($ids)) {
         return Helper::authorise($area, $component_name);
     }
     // This should never happen unless you screw up overriding getIDsFromRequest in your model...
     if (!is_array($ids)) {
         $ids = array($ids);
     }
     // Check the asset permissions of each record
     $resource = Inflector::singularize($controller_name);
     $isEditState = $area == 'core.edit.state';
     foreach ($ids as $id) {
         $asset = $component_name . '.' . $resource . '.' . $id;
         // Dedicated permission found, check it!
         if (Helper::authorise($area, $asset)) {
             return true;
         }
         // No dedicated permissions. Fallback on edit.own.
         if (!$isEditState && Helper::authorise('core.edit.own', $asset) && $model->hasField('created_by')) {
             // Load the record
             $model->find(array('id' => $id));
             // Make sure the record can be loaded
             if ($model->getId()) {
                 // Now test the owner is the user.
                 $owner_id = (int) $model->created_by;
                 // If I am the owner the test is successful
                 if ($owner_id == \JFactory::getUser()->id) {
                     return true;
                 }
             }
         }
     }
     return false;
 }
Example #3
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;
 }
Example #4
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;
 }
Example #5
0
 /**
  * Check the data for validity. By default it only checks for fields declared as NOT NULL
  *
  * @return  static  Self, for chaining
  *
  * @throws \RuntimeException  When the data bound to this record is invalid
  */
 public function check()
 {
     if (!$this->autoChecks) {
         return $this;
     }
     foreach ($this->knownFields as $fieldName => $field) {
         // Never check the key if it's empty; an empty key is normal for new records
         if ($fieldName == $this->idFieldName) {
             continue;
         }
         $value = $this->{$fieldName};
         if ($field->Null == 'NO' && empty($value) && !is_numeric($value) && !in_array($fieldName, $this->fieldsSkipChecks)) {
             $text = $this->container->application->getName() . '_' . Inflector::singularize($this->getName()) . '_ERR_' . $fieldName . '_EMPTY';
             throw new \RuntimeException(Text::_($text), 500);
         }
     }
     return $this;
 }
Example #6
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;
 }
Example #7
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));
     }
 }