Example #1
0
 public function __construct($container = null)
 {
     if (!is_object($container)) {
         $container = Application::getInstance()->getContainer();
     }
     parent::__construct();
     $config = $container->appConfig;
     $smtpauth = $config->get('mail.smtpauth') == 0 ? null : 1;
     $smtpuser = $config->get('mail.smtpuser');
     $smtppass = $config->get('mail.smtppass');
     $smtphost = $config->get('mail.smtphost');
     $smtpsecure = $config->get('mail.smtpsecure');
     $smtpport = $config->get('mail.smtpport');
     $mailfrom = $config->get('mail.mailfrom');
     $fromname = $config->get('mail.fromname');
     $mailer = $config->get('mail.mailer');
     $this->SetFrom($mailfrom, $fromname);
     $this->container = $container;
     switch ($mailer) {
         case 'smtp':
             $this->useSMTP($smtpauth, $smtphost, $smtpuser, $smtppass, $smtpsecure, $smtpport);
             break;
         case 'sendmail':
             $this->IsSendmail();
             break;
         default:
             $this->IsMail();
             break;
     }
 }
Example #2
0
 /**
  * Public constructor. Creates a new User Manager. Do not call this directly. It's best to call getInstance()
  * instead.
  *
  * @param   Container   $container
  */
 public function __construct(Container $container = null)
 {
     if (!is_object($container)) {
         $container = Application::getInstance()->getContainer();
     }
     $this->user_table = $container->appConfig->get('user_table', '#__users');
     $this->user_class = $container->appConfig->get('user_class', '\\Awf\\User\\User');
     $this->container = $container;
 }
Example #3
0
 /**
  * Constructor.
  *
  * @param   integer      $total       The total number of items.
  * @param   integer      $limitStart  The offset of the item to start at.
  * @param   integer      $limit       The number of items to display per page.
  * @param   integer      $displayed   Maximum number of page links to display (default: 10)
  * @param   Application  $app         The application this pagination object is attached to
  */
 public function __construct($total, $limitStart, $limit, $displayed = 10, $app = null)
 {
     if (!is_object($app) || !$app instanceof Application) {
         $app = Application::getInstance();
     }
     $this->application = $app;
     // Value/type checking.
     $this->total = (int) $total;
     $this->limitStart = (int) max($limitStart, 0);
     $this->limit = (int) max($limit, 0);
     if ($this->limit > $this->total) {
         $this->limitStart = 0;
     }
     if (!$this->limit) {
         $this->limit = $total;
         $this->limitStart = 0;
     }
     /*
      * If limitStart is greater than total (i.e. we are asked to display records that don't exist)
      * then set limitStart to display the last natural page of results
      */
     if ($this->limitStart > $this->total - $this->limit) {
         $this->limitStart = max(0, (int) (ceil($this->total / $this->limit) - 1) * $this->limit);
     }
     // Set the total pages and current page values.
     if ($this->limit > 0) {
         $this->pagesTotal = ceil($this->total / $this->limit);
         $this->pagesCurrent = ceil(($this->limitStart + 1) / $this->limit);
     }
     // Set the pagination iteration loop values.
     $this->pagesDisplayed = $displayed;
     $displayedPages = $this->pagesDisplayed;
     $this->pagesStart = $this->pagesCurrent - $displayedPages / 2;
     if ($this->pagesStart < 1) {
         $this->pagesStart = 1;
     }
     if ($this->pagesStart + $displayedPages > $this->pagesTotal) {
         $this->pagesStop = $this->pagesTotal;
         if ($this->pagesTotal < $displayedPages) {
             $this->pagesStart = 1;
         } else {
             $this->pagesStart = $this->pagesTotal - $displayedPages + 1;
         }
     } else {
         $this->pagesStop = $this->pagesStart + $displayedPages - 1;
     }
     // If we are viewing all records set the view all flag to true.
     if ($limit == 0) {
         $this->viewAll = true;
     }
     // Automatically set the URL parameters
     $this->setAdditionalUrlParamsFromInput();
 }
Example #4
0
 /**
  * Checks for snooping outside of the file system root.
  *
  * @param   string  $path  A file system path to check.
  * @param   string  $ds    Directory separator (optional).
  *
  * @return  string  A cleaned version of the path or exit on error.
  *
  * @throws  \Exception  When malicious activity is detected
  */
 public static function check($path, $ds = DIRECTORY_SEPARATOR)
 {
     if (strpos($path, '..') !== false) {
         // Don't translate
         throw new \Exception(__CLASS__ . '::check Use of relative paths not permitted', 20);
     }
     $rootPath = Application::getInstance()->getContainer()->filesystemBase;
     $path = self::clean($path);
     if ($rootPath != '' && strpos($path, self::clean($rootPath)) !== 0) {
         // Don't translate
         throw new \Exception(__CLASS__ . '::check Snooping out of bounds @ ' . $path, 20);
     }
     return $path;
 }
Example #5
0
 /**
  * Add unobtrusive JavaScript support for a calendar control.
  *
  * @param   Application  $app  CSS and JS will be added to the document of the selected application
  *
  * @return  void
  */
 public static function calendar(Application $app = null)
 {
     // Only load once
     if (isset(static::$loaded[__METHOD__])) {
         return;
     }
     if (!is_object($app)) {
         $app = Application::getInstance();
     }
     $document = $app->getDocument();
     Template::addJs('media://js/datepicker/bootstrap-datepicker.js');
     Template::addCss('media://css/datepicker.css');
     static::$loaded[__METHOD__] = true;
 }
Example #6
0
 /**
  * Public constructor
  *
  * @param   Container $container The container this dispatcher belongs to
  */
 public function __construct($container = null)
 {
     if (!is_object($container) || !$container instanceof Container) {
         $container = Application::getInstance()->getContainer();
     }
     $this->container = $container;
     $this->input = $container->input;
     // Get the default values for the view and layout names
     $this->view = $this->input->getCmd('view', null);
     $this->layout = $this->input->getCmd('layout', null);
     // Not redundant; you may pass an empty but non-null view which is invalid, so we need the fallback
     if (empty($this->view)) {
         $this->view = $this->defaultView;
         $this->container->input->set('view', $this->view);
     }
 }
Example #7
0
 /**
  * Public constructor. Initialises the relation.
  *
  * @param   DataModel  $parentModel        The data model we are attached to
  * @param   string     $foreignModelClass  The class name of the foreign key's model
  * @param   string     $localKey           The local table key for this relation, default: parentModel's ID field name
  * @param   string     $foreignKey         The foreign key for this relation, default: parentModel's ID field name
  * @param   string     $pivotTable         IGNORED
  * @param   string     $pivotLocalKey      IGNORED
  * @param   string     $pivotForeignKey    IGNORED
  */
 public function __construct(DataModel $parentModel, $foreignModelClass, $localKey = null, $foreignKey = null, $pivotTable = null, $pivotLocalKey = null, $pivotForeignKey = null)
 {
     parent::__construct($parentModel, $foreignModelClass, $localKey, $foreignKey, $pivotTable, $pivotLocalKey, $pivotForeignKey);
     if (empty($localKey)) {
         // Get a model instance
         $container = Application::getInstance($this->foreignModelApp)->getContainer();
         /** @var DataModel $foreignModel */
         $foreignModel = DataModel::getTmpInstance($this->foreignModelApp, $this->foreignModelName, $container);
         $this->localKey = $foreignModel->getIdFieldName();
     }
     if (empty($foreignKey)) {
         if (!isset($foreignModel)) {
             // Get a model instance
             $container = Application::getInstance($this->foreignModelApp)->getContainer();
             /** @var DataModel $foreignModel */
             $foreignModel = DataModel::getTmpInstance($this->foreignModelApp, $this->foreignModelName, $container);
         }
         $this->foreignKey = $foreignModel->getIdFieldName();
     }
 }
Example #8
0
 /**
  * Public constructor
  *
  * @param   Container $container  The container attached to this application
  *
  * @return   Cli
  */
 public function __construct(Container $container = null)
 {
     // Close the application if we are not executed from the command line, Akeeba style (allow for PHP CGI)
     if (array_key_exists('REQUEST_METHOD', $_SERVER)) {
         die('You are not supposed to access this script from the web. You have to run it from the command line.');
     }
     if (empty($container['application_name'])) {
         $container->application_name = 'cli';
         $this->name = 'cli';
     }
     parent::__construct($container);
     if (!$container->input instanceof \Awf\Input\Cli) {
         // Create an input object
         $cgiMode = false;
         if (!defined('STDOUT') || !defined('STDIN') || !isset($_SERVER['argv'])) {
             $cgiMode = true;
         }
         if ($cgiMode) {
             $query = "";
             if (!empty($_GET)) {
                 foreach ($_GET as $k => $v) {
                     $query .= " {$k}";
                     if ($v != "") {
                         $query .= "={$v}";
                     }
                 }
             }
             $query = ltrim($query);
             $argv = explode(' ', $query);
             $argc = count($argv);
             $_SERVER['argv'] = $argv;
         }
         unset($container['input']);
         $container['input'] = new \Awf\Input\Cli();
         try {
         } catch (\Exception $e) {
         }
     }
     self::$instances['cli'] = $this;
 }
Example #9
0
 /**
  * Get a filesystem abstraction adapter based on the configuration of the provided application object
  *
  * @param   Container  $container  The application which provides the configuration
  * @param   boolean      $hybrid       Should I return a hybrid adapter?
  *
  * @return  FilesystemInterface  The filesystem abstraction adapter
  */
 public static function getAdapter(Container $container = null, $hybrid = false)
 {
     if (!is_object($container)) {
         $container = Application::getInstance()->getContainer();
     }
     $config = $container->appConfig;
     $defaultPort = $config->get('fs.driver', 'file') == 'ftp' ? '21' : '22';
     $options = array('driver' => $config->get('fs.driver', 'file'), 'host' => $config->get('fs.host', 'localhost'), 'port' => $config->get('fs.port', $defaultPort), 'username' => $config->get('fs.username', ''), 'password' => $config->get('fs.password', ''), 'directory' => $config->get('fs.dir', ''), 'ssl' => $config->get('fs.ssl', false), 'passive' => $config->get('fs.passive', true));
     $classPrefix = '\\Awf\\Filesystem\\';
     $className = $classPrefix . ucfirst($options['driver']);
     if (!class_exists($className)) {
         $hybrid = false;
         $className = $classPrefix . 'File';
     } elseif ($hybrid) {
         $className = $classPrefix . 'Hybrid';
     }
     $signature = md5($container->application_name . $className . ($hybrid ? 'hybrid' : ''));
     if (!isset(self::$instances[$signature])) {
         self::$instances[$signature] = new $className($options);
     }
     return self::$instances[$signature];
 }
Example #10
0
 /**
  * Returns a new item of the foreignModel type, pre-initialised to fulfil this relation
  *
  * @return DataModel
  *
  * @throws DataModel\Relation\Exception\NewNotSupported when it's not supported
  */
 public function getNew()
 {
     // Get a model instance
     $container = Application::getInstance($this->foreignModelApp)->getContainer();
     /** @var DataModel $foreignModel */
     $foreignModel = DataModel::getTmpInstance($this->foreignModelApp, $this->foreignModelName, $container);
     // Prime the model
     $foreignModel->setFieldValue($this->foreignKey, $this->parentModel->getFieldValue($this->localKey));
     // Make sure we do have a data list
     if (!$this->data instanceof Collection) {
         $this->getData();
     }
     // Add the model to the data list
     $this->data->add($foreignModel);
     return $this->data->last();
 }
Example #11
0
 /**
  * Automatically detect the language preferences from the browser, choosing
  * the best fit language that exists on our system or falling back to en-GB
  * when no preferred language exists.
  *
  * @param   string $appName      The application's name to load language strings for
  * @param   string $suffix       The suffix of the language file, by default it's .ini
  * @param   string $languagePath The base path to the language files (optional)
  *
  * @return  string  The language code
  */
 public static function detectLanguage($appName = null, $suffix = '.ini', $languagePath = null)
 {
     if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
         $languages = strtolower($_SERVER["HTTP_ACCEPT_LANGUAGE"]);
         // $languages = ' fr-ch;q=0.3, da, en-us;q=0.8, en;q=0.5, fr;q=0.3';
         // need to remove spaces from strings to avoid error
         $languages = str_replace(' ', '', $languages);
         $languages = explode(",", $languages);
         // First we need to sort languages by their weight
         $temp = array();
         foreach ($languages as $lang) {
             $parts = explode(';', $lang);
             $q = 1;
             if (count($parts) > 1 && substr($parts[1], 0, 2) == 'q=') {
                 $q = floatval(substr($parts[1], 2));
             }
             $temp[$parts[0]] = $q;
         }
         arsort($temp);
         $languages = $temp;
         foreach ($languages as $language => $weight) {
             // pull out the language, place languages into array of full and primary
             // string structure:
             $temp_array = array();
             // slice out the part before the dash, place into array
             $temp_array[0] = $language;
             //full language
             $parts = explode('-', $language);
             $temp_array[1] = $parts[0];
             // cut out primary language
             if (strlen($temp_array[0]) == 5 && (substr($temp_array[0], 2, 1) == '-' || substr($temp_array[0], 2, 1) == '_')) {
                 $langLocation = strtoupper(substr($temp_array[0], 3, 2));
                 $temp_array[0] = $temp_array[1] . '-' . $langLocation;
             }
             //place this array into main $user_languages language array
             $user_languages[] = $temp_array;
         }
         if (!isset($user_languages)) {
             return 'en-GB';
         }
         if (empty($appName)) {
             $appName = Application::getInstance()->getName();
         }
         if (empty($languagePath)) {
             $languagePath = Application::getInstance($appName)->getContainer()->languagePath;
         }
         $baseName = $languagePath . '/' . strtolower($appName) . '/';
         if (!@is_dir($baseName)) {
             $baseName = $languagePath . '/';
         }
         if (!@is_dir($baseName)) {
             return 'en-GB';
         }
         // Look for classic file layout
         foreach ($user_languages as $languageStruct) {
             // Search for exact language
             $langFilename = $baseName . $languageStruct[0] . $suffix;
             if (!file_exists($langFilename)) {
                 $langFilename = '';
                 $filesystem = new File(array());
                 $allFiles = $filesystem->directoryFiles($baseName, $languageStruct[1] . '\\-.*', false, true);
                 if (count($allFiles)) {
                     $langFilename = array_shift($allFiles);
                 }
             }
             if (!empty($langFilename) && file_exists($langFilename)) {
                 return basename($langFilename, $suffix);
             }
         }
         // Look for subdirectory layout
         $allFolders = array();
         try {
             $di = new \DirectoryIterator($baseName);
         } catch (\Exception $e) {
             return 'en-GB';
         }
         /** @var \DirectoryIterator $file */
         foreach ($di as $file) {
             if ($di->isDot()) {
                 continue;
             }
             if (!$di->isDir()) {
                 continue;
             }
             $allFolders[] = $file->getFilename();
         }
         foreach ($user_languages as $languageStruct) {
             if (array_key_exists($languageStruct[0], $allFolders)) {
                 return $languageStruct[0];
             }
             foreach ($allFolders as $folder) {
                 if (strpos($folder, $languageStruct[1]) === 0) {
                     return $folder;
                 }
             }
         }
     }
     return 'en-GB';
 }
Example #12
0
 /**
  * Method to return a Driver instance based on the given options.  There are three global options and then
  * the rest are specific to the database driver.  The 'driver' option defines which Driver class is
  * used for the connection -- the default is 'mysqli'.  The 'database' option determines which database is to
  * be used for the connection.  The 'select' option determines whether the connector should automatically select
  * the chosen database.
  *
  * Instances are unique to the given options and new objects are only created when a unique options array is
  * passed into the method.  This ensures that we don't end up with unnecessary database connection resources.
  *
  * @param   array|Container $options Parameters to be passed to the database driver or a DI Container to read app
  *                                   config from.
  *
  * @return  Driver  A database object.
  *
  * @throws  \RuntimeException  When the driver cannot be instantiated
  */
 public static function getInstance($options = array())
 {
     // If no options are passed, push the default application into the options. This will result in the
     // default driver object instance for the app to be created.
     if (empty($options)) {
         $options = Application::getInstance()->getContainer();
     }
     // If an application is passed in the options ignore everything else and set up based on app configuration
     if (is_object($options) && $options instanceof Container) {
         $config = $options->appConfig;
         $options = array('driver' => $config->get('dbdriver', 'mysqli'), 'database' => $config->get('dbname', 'solo'), 'select' => true, 'host' => $config->get('dbhost', 'localhost'), 'user' => $config->get('dbuser', ''), 'password' => $config->get('dbpass', ''), 'prefix' => $config->get('prefix', 'solo_'));
     }
     // Sanitize the database connector options.
     $options['driver'] = isset($options['driver']) ? preg_replace('/[^A-Z0-9_\\.-]/i', '', $options['driver']) : 'mysqli';
     $options['database'] = isset($options['database']) ? $options['database'] : null;
     $options['select'] = isset($options['select']) ? $options['select'] : true;
     // Get the options signature for the database connector.
     $signature = md5(serialize($options));
     // If we already have a database connector instance for these options then just use that.
     if (empty(self::$instances[$signature])) {
         // Derive the class name from the driver.
         $class = '\\Awf\\Database\\Driver\\' . ucfirst(strtolower($options['driver']));
         // If the class still doesn't exist we have nothing left to do but throw an exception.  We did our best.
         if (!class_exists($class)) {
             throw new \RuntimeException(sprintf('Unable to load Database Driver: %s', $options['driver']));
         }
         // Create our new Driver connector based on the options given.
         try {
             $instance = new $class($options);
         } catch (\RuntimeException $e) {
             throw new \RuntimeException(sprintf('Unable to connect to the Database: %s', $e->getMessage()));
         }
         // Set the new connector to the global instances based on signature.
         self::$instances[$signature] = $instance;
     }
     return self::$instances[$signature];
 }
Example #13
0
 /**
  * Redirects the browser or returns false if no redirect is set.
  *
  * @return  boolean  False if no redirect exists.
  */
 public function redirect()
 {
     if ($this->redirect) {
         $app = Application::getInstance();
         $app->redirect($this->redirect, $this->message, $this->messageType);
     }
     return false;
 }
Example #14
0
 /**
  * Returns the count subquery for DataModel's has() and whereHas() methods.
  *
  * @return Query
  */
 public function getCountSubquery()
 {
     // Get a model instance
     $container = Application::getInstance($this->foreignModelApp)->getContainer();
     /** @var DataModel $foreignModel */
     $foreignModel = DataModel::getTmpInstance($this->foreignModelApp, $this->foreignModelName, $container);
     $db = $foreignModel->getDbo();
     $query = $db->getQuery(true)->select('COUNT(*)')->from($db->qn($foreignModel->getTableName()) . ' AS ' . $db->qn('reltbl'))->innerJoin($db->qn($this->pivotTable) . ' AS ' . $db->qn('pivotTable') . ' ON(' . $db->qn('pivotTable') . '.' . $db->qn($this->pivotForeignKey) . ' = ' . $db->qn('reltbl') . '.' . $db->qn($foreignModel->getFieldAlias($this->foreignKey)) . ')')->where($db->qn('pivotTable') . '.' . $db->qn($this->pivotLocalKey) . ' =' . $db->qn($this->parentModel->getTableName()) . '.' . $db->qn($this->parentModel->getFieldAlias($this->localKey)));
     return $query;
 }
Example #15
0
 /**
  * Performs the staggered download of file.
  *
  * @param   array $params A parameters array, as sent by the user interface
  *
  * @return  array  A return status array
  */
 public function importFromURL($params)
 {
     $this->params = $params;
     // Fetch data
     $filename = $this->getParam('file');
     $frag = $this->getParam('frag', -1);
     $totalSize = $this->getParam('totalSize', -1);
     $doneSize = $this->getParam('doneSize', -1);
     $maxExecTime = $this->getParam('maxExecTime', 5);
     $runTimeBias = $this->getParam('runTimeBias', 75);
     $minExecTime = $this->getParam('minExecTime', 1);
     $localFilename = 'download.zip';
     $tmpDir = Application::getInstance()->getContainer()->temporaryPath;
     $tmpDir = rtrim($tmpDir, '/\\');
     $localFilename = $this->getParam('localFilename', $localFilename);
     // Init retArray
     $retArray = array("status" => true, "error" => '', "frag" => $frag, "totalSize" => $totalSize, "doneSize" => $doneSize, "percent" => 0);
     try {
         $timer = new Timer($minExecTime, $runTimeBias);
         $start = $timer->getRunningTime();
         // Mark the start of this download
         $break = false;
         // Don't break the step
         // Figure out where on Earth to put that file
         $local_file = $tmpDir . '/' . $localFilename;
         //debugMsg("- Importing from $filename");
         while ($timer->getTimeLeft() > 0 && !$break) {
             // Do we have to initialize the file?
             if ($frag == -1) {
                 //debugMsg("-- First frag, killing local file");
                 // Currently downloaded size
                 $doneSize = 0;
                 if (@file_exists($local_file)) {
                     @unlink($local_file);
                 }
                 // Delete and touch the output file
                 $fp = @fopen($local_file, 'wb');
                 if ($fp !== false) {
                     @fclose($fp);
                 }
                 // Init
                 $frag = 0;
                 //debugMsg("-- First frag, getting the file size");
                 $retArray['totalSize'] = $this->adapter->getFileSize($filename);
                 $totalSize = $retArray['totalSize'];
             }
             // Calculate from and length
             $length = 1048576;
             $from = $frag * $length;
             $to = $length + $from - 1;
             // Try to download the first frag
             $required_time = 1.0;
             //debugMsg("-- Importing frag $frag, byte position from/to: $from / $to");
             try {
                 $result = $this->adapter->downloadAndReturn($filename, $from, $to);
                 if ($result === false) {
                     throw new \Exception(Text::sprintf('AWF_DOWNLOAD_ERR_LIB_COULDNOTDOWNLOADFROMURL', $filename), 500);
                 }
             } catch (\Exception $e) {
                 $result = false;
                 $error = $e->getMessage();
             }
             if ($result === false) {
                 // Failed download
                 if ($frag == 0) {
                     // Failure to download first frag = failure to download. Period.
                     $retArray['status'] = false;
                     $retArray['error'] = $error;
                     //debugMsg("-- Download FAILED");
                     return $retArray;
                 } else {
                     // Since this is a staggered download, consider this normal and finish
                     $frag = -1;
                     //debugMsg("-- Import complete");
                     $totalSize = $doneSize;
                     $break = true;
                 }
             }
             // Add the currently downloaded frag to the total size of downloaded files
             if ($result) {
                 $filesize = strlen($result);
                 //debugMsg("-- Successful download of $filesize bytes");
                 $doneSize += $filesize;
                 // Append the file
                 $fp = @fopen($local_file, 'ab');
                 if ($fp === false) {
                     //debugMsg("-- Can't open local file $local_file for writing");
                     // Can't open the file for writing
                     $retArray['status'] = false;
                     $retArray['error'] = Text::sprintf('AWF_DOWNLOAD_ERR_LIB_COULDNOTWRITELOCALFILE', $local_file);
                     return $retArray;
                 }
                 fwrite($fp, $result);
                 fclose($fp);
                 //debugMsg("-- Appended data to local file $local_file");
                 $frag++;
                 //debugMsg("-- Proceeding to next fragment, frag $frag");
                 if ($filesize < $length || $filesize > $length) {
                     // A partial download or a download larger than the frag size means we are done
                     $frag = -1;
                     //debugMsg("-- Import complete (partial download of last frag)");
                     $totalSize = $doneSize;
                     $break = true;
                 }
             }
             // Advance the frag pointer and mark the end
             $end = $timer->getRunningTime();
             // Do we predict that we have enough time?
             $required_time = max(1.1 * ($end - $start), $required_time);
             if ($required_time > 10 - $end + $start) {
                 $break = true;
             }
             $start = $end;
         }
         if ($frag == -1) {
             $percent = 100;
         } elseif ($doneSize <= 0) {
             $percent = 0;
         } else {
             if ($totalSize > 0) {
                 $percent = 100 * ($doneSize / $totalSize);
             } else {
                 $percent = 0;
             }
         }
         // Update $retArray
         $retArray = array("status" => true, "error" => '', "frag" => $frag, "totalSize" => $totalSize, "doneSize" => $doneSize, "percent" => $percent);
     } catch (\Exception $e) {
         //debugMsg("EXCEPTION RAISED:");
         //debugMsg($e->getMessage());
         $retArray['status'] = false;
         $retArray['error'] = $e->getMessage();
     }
     return $retArray;
 }
Example #16
0
 /**
  * Get the relation data.
  *
  * If you want to apply additional filtering to the foreign model, use the $callback. It can be any function,
  * static method, public method or closure with an interface of function(DataModel $foreignModel). You are not
  * supposed to return anything, just modify $foreignModel's state directly. For example, you may want to do:
  * $foreignModel->setState('foo', 'bar')
  *
  * @param callable   $callback The callback to run on the remote model.
  * @param Collection $dataCollection
  *
  * @return Collection|DataModel
  */
 public function getData(callable $callback = null, Collection $dataCollection = null)
 {
     if (is_null($this->data)) {
         // Initialise
         $this->data = new Collection();
         // Get a model instance
         $container = Application::getInstance($this->foreignModelApp)->getContainer();
         /** @var DataModel $foreignModel */
         $foreignModel = DataModel::getTmpInstance($this->foreignModelApp, $this->foreignModelName, $container)->setIgnoreRequest(true);
         $filtered = $this->filterForeignModel($foreignModel, $dataCollection);
         if (!$filtered) {
             return $this->data;
         }
         // Apply the callback, if applicable
         if (!is_null($callback) && is_callable($callback)) {
             call_user_func($callback, $foreignModel);
         }
         // Get the list of items from the foreign model and cache in $this->data
         $this->data = $foreignModel->get(true);
     }
     return $this->data;
 }
Example #17
0
 public function __construct(array $values = array())
 {
     $this->application_name = '';
     $this->session_segment_name = null;
     $this->basePath = null;
     $this->templatePath = null;
     $this->languagePath = null;
     $this->temporaryPath = null;
     $this->filesystemBase = null;
     $this->sqlPath = null;
     parent::__construct($values);
     // Application service
     if (!isset($this['application'])) {
         $this['application'] = function (Container $c) {
             return Application::getInstance($c->application_name, $c);
         };
     }
     // Application Configuration service
     if (!isset($this['appConfig'])) {
         $this['appConfig'] = function (Container $c) {
             return new \Awf\Application\Configuration($c);
         };
     }
     // Database Driver service
     if (!isset($this['db'])) {
         $this['db'] = function (Container $c) {
             return Driver::getInstance($c);
         };
     }
     // Application Dispatcher service
     if (!isset($this['dispatcher'])) {
         $this['dispatcher'] = function (Container $c) {
             $className = '\\' . ucfirst($c->application_name) . '\\Dispatcher';
             if (!class_exists($className)) {
                 $className = '\\Awf\\Dispatcher\\Dispatcher';
             }
             return new $className($c);
         };
     }
     // Application Event Dispatcher service
     if (!isset($this['eventDispatcher'])) {
         $this['eventDispatcher'] = function (Container $c) {
             return new \Awf\Event\Dispatcher($c);
         };
     }
     // Filesystem Abstraction Layer service
     if (!isset($this['fileSystem'])) {
         $this['fileSystem'] = function (Container $c) {
             return \Awf\Filesystem\Factory::getAdapter($c, true);
         };
     }
     // Input Access service
     if (!isset($this['input'])) {
         $this['input'] = function (Container $c) {
             return new \Awf\Input\Input();
         };
     }
     // Mailer Object service
     if (!isset($this['mailer'])) {
         $this['mailer'] = $this->factory(function (Container $c) {
             return new \Awf\Mailer\Mailer($c);
         });
     }
     // Application Router service
     if (!isset($this['router'])) {
         $this['router'] = function (Container $c) {
             return new \Awf\Router\Router($c);
         };
     }
     // Session Manager service
     if (!isset($this['session'])) {
         $this['session'] = function () {
             return new Session\Manager(new Session\SegmentFactory(), new Session\CsrfTokenFactory(new Session\Randval(new Phpfunc())), $_COOKIE);
         };
     }
     // Application Session Segment service
     if (!isset($this['segment'])) {
         $this['segment'] = function (Container $c) {
             if (empty($c->session_segment_name)) {
                 $c->session_segment_name = 'Akeeba\\Awf\\' . $c->application_name;
             }
             return $c->session->newSegment($c->session_segment_name);
         };
     }
     // User Manager service
     if (!isset($this['userManager'])) {
         $this['userManager'] = function (Container $c) {
             return new \Awf\User\Manager($c);
         };
     }
 }
Example #18
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;
         }
     }
 }
Example #19
0
    /**
     * Displays a calendar control field
     *
     * @param   string       $value    The date value
     * @param   string       $name     The name of the text field
     * @param   string       $id       The id of the text field
     * @param   string       $format   The date format
     * @param   array        $attribs  Additional HTML attributes
     * @param   Application  $app      The application to get the configuration from
     *
     * @return  string  HTML markup for a calendar field
     */
    public static function calendar($value, $name, $id, $format = 'yyyy-mm-dd', $attribs = null, Application $app = null)
    {
        static $done;
        if (!is_object($app)) {
            $app = Application::getInstance();
        }
        if ($done === null) {
            $done = array();
        }
        $attribs['class'] = isset($attribs['class']) ? $attribs['class'] : 'form-control';
        $attribs['class'] = trim($attribs['class'] . ' hasTooltip calendar');
        $readonly = isset($attribs['readonly']) && $attribs['readonly'] == 'readonly';
        $disabled = isset($attribs['disabled']) && $attribs['disabled'] == 'disabled';
        if (is_array($attribs)) {
            $attribs = ArrayHelper::toString($attribs);
        }
        if (!$readonly && !$disabled) {
            // Load the calendar behavior
            Behaviour::calendar();
            // Only display the triggers once for each control.
            if (!in_array($id, $done)) {
                // @todo Implement a way for the application to override the language
                $lang = Text::detectLanguage($app->getName());
                $document = $app->getDocument();
                $document->addScriptDeclaration(<<<JS
akeeba.jQuery(document).ready(function(){
\takeeba.jQuery('#{$id}-container').datepicker({
\t\tformat: "{$format}",
\t\ttodayBtn: "linked",
\t\tlanguage: "{$lang}",
\t\tautoclose: true
\t});
})
JS
);
                $done[] = $id;
            }
            return '<div class="input-group date" id="' . $id . '-container"><input type="text" title="' . (0 !== (int) $value ? static::date($value, null, null) : '') . '" name="' . $name . '" id="' . $id . '" value="' . htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '" ' . $attribs . ' />' . '<span class="input-group-btn" id="' . $id . '_img"><span class="btn btn-default"><span class="glyphicon glyphicon-calendar"></span></span></span></div>';
        } else {
            return '<input type="text" title="' . (0 !== (int) $value ? static::date($value, null, null) : '') . '" value="' . (0 !== (int) $value ? static::_('date', $value, 'Y-m-d H:i:s', null) : '') . '" ' . $attribs . ' /><input type="hidden" name="' . $name . '" id="' . $id . '" value="' . htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '" />';
        }
    }
Example #20
0
 /**
  * Parse a fancy path definition into a path relative to the site's root.
  * It returns both the normal and alternative (template media override) path.
  * For example, media://com_foobar/css/test.css is parsed into
  * array(
  *   'normal' => 'media/com_foobar/css/test.css',
  *   'alternate' => 'templates/mytemplate/media/com_foobar/css//test.css'
  * );
  *
  * The valid protocols are:
  * media://		The media directory or a media override
  * site://		Path relative to site's root (no alternate)
  *
  * @param   string       $path  Fancy path
  * @param   Application  $app   The application we're operating under
  *
  * @return  array  Array of normal and alternate parsed path
  */
 public static function getAltPaths($path, $app = null)
 {
     if (!is_object($app)) {
         $app = Application::getInstance();
     }
     $protoAndPath = explode('://', $path, 2);
     if (count($protoAndPath) < 2) {
         $protocol = 'media';
     } else {
         $protocol = $protoAndPath[0];
         $path = $protoAndPath[1];
     }
     $path = ltrim($path, '/' . DIRECTORY_SEPARATOR);
     switch ($protocol) {
         case 'media':
             // Do we have a media override in the template?
             $pathAndParams = explode('?', $path, 2);
             // Get the path of the templates directory relative to the file system base
             $rootPath = realpath($app->getContainer()->filesystemBase);
             $templateRelativePath = realpath($app->getContainer()->templatePath);
             if ($templateRelativePath == $rootPath) {
                 $templateRelativePath = '';
             } elseif (strpos($templateRelativePath, $rootPath) === 0) {
                 $templateRelativePath = substr($templateRelativePath, strlen($rootPath));
                 $templateRelativePath = trim($templateRelativePath, DIRECTORY_SEPARATOR . '/\\') . '/';
             }
             $templateRelativePath = str_replace('\\', '/', $templateRelativePath);
             // Return the alternative paths
             $ret = array('normal' => 'media/' . $pathAndParams[0], 'alternate' => $templateRelativePath . $app->getTemplate() . '/media/' . $pathAndParams[0]);
             break;
         default:
         case 'site':
             $ret = array('normal' => $path);
             break;
     }
     // For CSS and JS files, add a debug path if the supplied file is compressed
     $ext = pathinfo($ret['normal'], PATHINFO_EXTENSION);
     if (in_array($ext, array('css', 'js'))) {
         $file = basename($ret['normal'], '.' . $ext);
         if (strlen($file) > 4 && strrpos($file, '.min', '-4')) {
             $position = strrpos($file, '.min', '-4');
             $filename = str_replace('.min', '.', $file, $position) . $ext;
         } else {
             $filename = $file . '-uncompressed.' . $ext;
         }
         // Clone the $ret array so we can manipulate the 'normal' path a bit
         $t1 = (object) $ret;
         $temp = clone $t1;
         unset($t1);
         $temp = (array) $temp;
         $normalPath = explode('/', $temp['normal']);
         array_pop($normalPath);
         $normalPath[] = $filename;
         $ret['debug'] = implode('/', $normalPath);
     }
     return $ret;
 }
Example #21
0
 /**
  * Public class constructor
  *
  * You can use the $container['mvc_config'] array to pass some configuration values to the object:
  * state			stdClass|array. The state variables of the Model.
  * use_populate		Boolean. When true the model will set its state from populateState() instead of the request.
  * ignore_request	Boolean. When true getState will now automatically load state data from the request.
  *
  * @param   Container $container The configuration variables to this model
  */
 public function __construct(\Awf\Container\Container $container = null)
 {
     if (!is_object($container)) {
         $container = Application::getInstance()->getContainer();
     }
     $this->input = $container->input;
     $this->container = $container;
     $this->config = isset($container['mvc_config']) ? $container['mvc_config'] : array();
     // Set the model's name
     $this->name = $this->getName();
     // Set the model state
     if (array_key_exists('state', $this->config)) {
         if (is_object($this->config['state'])) {
             $this->state = $this->config['state'];
         } elseif (is_array($this->config['state'])) {
             $this->state = (object) $this->config['state'];
         } else {
             $this->state = new \stdClass();
         }
     } else {
         $this->state = new \stdClass();
     }
     // Set the internal state marker
     if (!empty($this->config['use_populate'])) {
         $this->_state_set = true;
     }
     // Set the internal state marker
     if (!empty($this->config['ignore_request'])) {
         $this->_ignoreRequest = true;
     }
 }
Example #22
0
 /**
  * Loads a template given any path. The path is in the format:
  * viewname/templatename
  *
  * @param   string $path        The template path
  * @param   array  $forceParams A hash array of variables to be extracted in the local scope of the template file
  *
  * @return  string  The output of the template
  *
  * @throws  \Exception  When the layout file is not found
  */
 public function loadAnyTemplate($path = '', $forceParams = array())
 {
     $template = \Awf\Application\Application::getInstance()->getTemplate();
     $layoutTemplate = $this->getLayoutTemplate();
     // Parse the path
     $templateParts = $this->parseTemplatePath($path);
     // Get the default paths
     $templatePath = $this->container->templatePath;
     $paths = array();
     $paths[] = $templatePath . '/' . $template . '/html/' . $this->input->getCmd('option', '') . '/' . $templateParts['view'];
     $paths[] = $this->container->basePath . '/views/' . $templateParts['view'] . '/tmpl';
     $paths[] = $this->container->basePath . '/View/' . $templateParts['view'] . '/tmpl';
     $paths = array_merge($paths, $this->templatePaths);
     // Look for a template override
     if (isset($layoutTemplate) && $layoutTemplate != '_' && $layoutTemplate != $template) {
         $apath = array_shift($paths);
         array_unshift($paths, str_replace($template, $layoutTemplate, $apath));
     }
     $filetofind = $templateParts['template'] . '.php';
     $this->_tempFilePath = \Awf\Utils\Path::find($paths, $filetofind);
     if ($this->_tempFilePath) {
         // Unset from local scope
         unset($template);
         unset($layoutTemplate);
         unset($paths);
         unset($path);
         unset($filetofind);
         // Never allow a 'this' property
         if (isset($this->this)) {
             unset($this->this);
         }
         // Force parameters into scope
         if (!empty($forceParams)) {
             extract($forceParams);
         }
         // Start capturing output into a buffer
         ob_start();
         // Include the requested template filename in the local scope
         // (this will execute the view logic).
         include $this->_tempFilePath;
         // Done with the requested template; get the buffer and
         // clear it.
         $this->output = ob_get_contents();
         ob_end_clean();
         return $this->output;
     } else {
         return new \Exception(\Awf\Text\Text::sprintf('AWF_APPLICATION_ERROR_LAYOUTFILE_NOT_FOUND', $path), 500);
     }
 }
Example #23
0
 /**
  * Returns the base URI for the request.
  *
  * @param   boolean   $pathonly  If false, prepend the scheme, host and port information. Default is false.
  * @param   Container $container The container to use for determining the live_site configuration value
  *
  * @return  string  The base URI string
  */
 public static function base($pathonly = false, Container $container = null)
 {
     // Get the base request path.
     if (empty(self::$base)) {
         if (!is_object($container)) {
             $container = Application::getInstance()->getContainer();
         }
         $config = $container->appConfig;
         $live_site = $config->get('live_site');
         if (trim($live_site) != '') {
             $uri = self::getInstance($live_site);
             self::$base['prefix'] = $uri->toString(array('scheme', 'host', 'port'));
             self::$base['path'] = rtrim($uri->toString(array('path')), '/\\');
         } else {
             $uri = self::getInstance();
             self::$base['prefix'] = $uri->toString(array('scheme', 'host', 'port'));
             if (strpos(php_sapi_name(), 'cgi') !== false && !ini_get('cgi.fix_pathinfo') && !empty($_SERVER['REQUEST_URI'])) {
                 // PHP-CGI on Apache with "cgi.fix_pathinfo = 0"
                 // We shouldn't have user-supplied PATH_INFO in PHP_SELF in this case
                 // because PHP will not work with PATH_INFO at all.
                 $script_name = $_SERVER['PHP_SELF'];
             } else {
                 // Others
                 $script_name = $_SERVER['SCRIPT_NAME'];
             }
             self::$base['path'] = rtrim(dirname($script_name), '/\\');
         }
     }
     return $pathonly === false ? self::$base['prefix'] . self::$base['path'] . '/' : self::$base['path'];
 }