Example #1
0
 /**
  * Load the data, don't forget to validate the incoming data
  *
  * @return	void
  */
 private function getData()
 {
     // get categories
     $categories = FrontendBlogModel::getAllCategories();
     $possibleCategories = array();
     foreach ($categories as $category) {
         $possibleCategories[$category['url']] = $category['id'];
     }
     // requested category
     $requestedCategory = SpoonFilter::getValue($this->URL->getParameter(1, 'string'), array_keys($possibleCategories), 'false');
     // requested page
     $requestedPage = $this->URL->getParameter('page', 'int', 1);
     // validate category
     if ($requestedCategory == 'false') {
         $this->redirect(FrontendNavigation::getURL(404));
     }
     // set category
     $this->category = $categories[$possibleCategories[$requestedCategory]];
     // set URL and limit
     $this->pagination['url'] = FrontendNavigation::getURLForBlock('blog', 'category') . '/' . $requestedCategory;
     $this->pagination['limit'] = FrontendModel::getModuleSetting('blog', 'overview_num_items', 10);
     // populate count fields in pagination
     $this->pagination['num_items'] = FrontendBlogModel::getAllForCategoryCount($requestedCategory);
     $this->pagination['num_pages'] = (int) ceil($this->pagination['num_items'] / $this->pagination['limit']);
     // redirect if the request page doesn't exists
     if ($requestedPage > $this->pagination['num_pages'] || $requestedPage < 1) {
         $this->redirect(FrontendNavigation::getURL(404));
     }
     // populate calculated fields in pagination
     $this->pagination['requested_page'] = $requestedPage;
     $this->pagination['offset'] = $this->pagination['requested_page'] * $this->pagination['limit'] - $this->pagination['limit'];
     // get articles
     $this->items = FrontendBlogModel::getAllForCategory($requestedCategory, $this->pagination['limit'], $this->pagination['offset']);
 }
Example #2
0
 /**
  * Load necessary data.
  *
  * @return	void.
  */
 private function loadData()
 {
     // get data
     $this->selectedTheme = $this->getParameter('theme', 'string');
     // build available themes
     $this->availableThemes = BackendModel::getThemes();
     // determine selected theme, based upon submitted form or default theme
     $this->selectedTheme = SpoonFilter::getValue($this->selectedTheme, array_keys($this->availableThemes), BackendModel::getModuleSetting('core', 'theme', 'core'));
 }
 /**
  * Load the selected theme, falling back to default if none specified.
  */
 private function loadData()
 {
     // get data
     $this->selectedTheme = $this->getParameter('theme', 'string');
     // build available themes
     foreach (Model::getThemes() as $theme) {
         $this->availableThemes[$theme['value']] = $theme['label'];
     }
     // determine selected theme, based upon submitted form or default theme
     $this->selectedTheme = \SpoonFilter::getValue($this->selectedTheme, array_keys($this->availableThemes), $this->get('fork.settings')->get('Core', 'theme', 'core'));
 }
Example #4
0
 /**
  * Redirect the browser with an optional delay and stop script execution.
  *
  * @return	void
  * @param	string $URL				The URL.
  * @param	int[optional] $code		The redirect code.
  * @param	int[optional] $delay	A delay, expressed in seconds.
  */
 public static function redirect($URL, $code = 302, $delay = null)
 {
     // redefine url
     $URL = (string) $URL;
     $code = SpoonFilter::getValue($code, array(301, 302), 302, 'int');
     // redirect headers
     self::setHeadersByCode($code);
     // delay execution
     if ($delay !== null) {
         sleep((int) $delay);
     }
     // redirect
     self::setHeaders("Location: {$URL}");
     // stop execution
     exit;
 }
 public function testGetValue()
 {
     // setup
     $id = '1337';
     $type = 'web';
     $animal = 'donkey';
     $animals = array('1337', 'web', 'donkey');
     // perform tests
     $this->assertEquals(1337, SpoonFilter::getValue($id, null, 0, 'int'));
     $this->assertEquals('web', SpoonFilter::getValue($type, array('web', 'print'), 'print'));
     $this->assertEquals('whale', SpoonFilter::getValue($animal, array('whale', 'horse'), 'whale'));
     $this->assertEquals('donkey', SpoonFilter::getValue($animal, null, 'whale'));
     $this->assertEquals(array('1337', 'web', 'donkey'), SpoonFilter::getValue($animals, null, null, 'array'));
     $this->assertEquals(array('1337', 'web'), SpoonFilter::getValue($animals, array('1337', 'web'), array('soep'), 'array'));
     $this->assertEquals(array('soep'), SpoonFilter::getValue(array('blikken doos'), array('1337', 'web'), array('soep'), 'array'));
 }
Example #6
0
 /**
  * Write an error/custom message to the log.
  *
  * @return	void
  * @param	string $message			The messages that should be logged.
  * @param	string[optional] $type	The type of message you want to log, possible values are: error, custom.
  */
 public static function write($message, $type = 'error')
 {
     // milliseconds
     list($milliseconds) = explode(' ', microtime());
     $milliseconds = round($milliseconds * 1000, 0);
     // redefine var
     $message = date('Y-m-d H:i:s') . ' ' . $milliseconds . 'ms | ' . $message . "\n";
     $type = SpoonFilter::getValue($type, array('error', 'custom'), 'error');
     // file
     $file = self::getPath() . '/' . $type . '.log';
     // rename if needed
     if ((int) @filesize($file) >= self::MAX_FILE_SIZE * 1024) {
         // start new log file
         SpoonDirectory::move($file, $file . '.' . date('Ymdhis'));
     }
     // write content
     SpoonFile::setContent($file, $message, true, true);
 }
Example #7
0
 /**
  * Checks of the filesize is greater, equal or smaller than the given number + units.
  *
  * @return	bool
  * @param	int $size					The size to use in the check.
  * @param	string[optional] $unit		The unit to use.
  * @param	string[optional] $operator	The operator to use, possible values are: smaller, equal, greater.
  * @param	string[optional] $error		The error message to set.
  */
 public function isFilesize($size, $unit = 'kb', $operator = 'smaller', $error = null)
 {
     // file has been uploaded
     if ($this->isFilled()) {
         // define size
         $actualSize = $this->getFileSize($unit, 0);
         // operator
         $operator = SpoonFilter::getValue(strtolower($operator), array('smaller', 'equal', 'greater'), 'smaller');
         // smaller
         if ($operator == 'smaller' && $actualSize < $size) {
             return true;
         }
         // equal
         if ($operator == 'equal' && $actualSize == $size) {
             return true;
         }
         // greater
         if ($operator == 'greater' && $actualSize > $size) {
             return true;
         }
     }
     // has error
     if ($error !== null) {
         $this->setError($error);
     }
     return false;
 }
Example #8
0
 /**
  * Retrieve the days of the week in a specified language.
  *
  * @return	array							An array with all the days in the requested language.
  * @param	string[optional] $language		The language to use (available languages can be found in SpoonLocale).
  * @param	bool[optional] $abbreviated		Should the days be abbreviated?
  * @param	string[optional] $firstDay		First day of the week (available options: monday, sunday).
  */
 public static function getWeekDays($language = 'en', $abbreviated = false, $firstDay = 'monday')
 {
     // init vars
     $language = SpoonFilter::getValue($language, self::$languages, 'en');
     $firstDay = SpoonFilter::getValue($firstDay, array('monday', 'sunday'), 'monday');
     $locale = array();
     // fetch file
     require 'data/' . $language . '.php';
     // data array
     $days = $abbreviated ? $locale['date']['days']['abbreviated'] : $locale['date']['days']['full'];
     // in some regions monday is not the first day of the week.
     if ($firstDay == 'monday') {
         $sunday = $days['sun'];
         unset($days['sun']);
         $days['sun'] = $sunday;
     }
     return $days;
 }
Example #9
0
 /**
  * Set column for the widget
  *
  * @param string $column Possible values are: left, middle, right.
  */
 protected function setColumn($column)
 {
     $allowedColumns = array('left', 'middle', 'right');
     $this->column = \SpoonFilter::getValue((string) $column, $allowedColumns, 'left');
 }
Example #10
0
 /**
  * Set the sorting method.
  *
  * @param	string[optional] $sortingMethod		Set the sorting method that should be used, possible values are: desc, asc.
  */
 public function setSortingMethod($sortingMethod = 'desc')
 {
     $aAllowedSortingMethods = array('asc', 'desc');
     // set sorting method
     self::$sortingMethod = SpoonFilter::getValue($sortingMethod, $aAllowedSortingMethods, 'desc');
 }
Example #11
0
 /**
  * Process the querystring
  */
 private function processQueryString()
 {
     // store the querystring local, so we don't alter it.
     $queryString = $this->getQueryString();
     // find the position of ? (which separates real URL and GET-parameters)
     $positionQuestionMark = mb_strpos($queryString, '?');
     // separate the GET-chunk from the parameters
     $getParameters = '';
     if ($positionQuestionMark === false) {
         $processedQueryString = $queryString;
     } else {
         $processedQueryString = mb_substr($queryString, 0, $positionQuestionMark);
         $getParameters = mb_substr($queryString, $positionQuestionMark);
     }
     // split into chunks, a Backend URL will always look like /<lang>/<module>/<action>(?GET)
     $chunks = (array) explode('/', trim($processedQueryString, '/'));
     // check if this is a request for a AJAX-file
     $isAJAX = isset($chunks[1]) && $chunks[1] == 'ajax';
     // get the language, this will always be in front
     $language = '';
     if (isset($chunks[1]) && $chunks[1] != '') {
         $language = \SpoonFilter::getValue($chunks[1], array_keys(BackendLanguage::getWorkingLanguages()), '');
     }
     // no language provided?
     if ($language == '' && !$isAJAX) {
         // remove first element
         array_shift($chunks);
         // redirect to login
         $this->redirect('/' . NAMED_APPLICATION . '/' . SITE_DEFAULT_LANGUAGE . (empty($chunks) ? '' : '/') . implode('/', $chunks) . $getParameters);
     }
     // get the module, null will be the default
     $module = isset($chunks[2]) && $chunks[2] != '' ? $chunks[2] : 'Dashboard';
     $module = \SpoonFilter::toCamelCase($module);
     // get the requested action, if it is passed
     if (isset($chunks[3]) && $chunks[3] != '') {
         $action = \SpoonFilter::toCamelCase($chunks[3]);
     } elseif (!$isAJAX) {
         // Check if we can load the config file
         $configClass = 'Backend\\Modules\\' . $module . '\\Config';
         if ($module == 'Core') {
             $configClass = 'Backend\\Core\\Config';
         }
         try {
             // when loading a backend url for a module that doesn't exist, without
             // providing an action, a FatalErrorException occurs, because the config
             // class we're trying to load doesn't exist. Let's just throw instead,
             // and catch it immediately.
             if (!class_exists($configClass)) {
                 throw new Exception('The config class does not exist');
             }
             /** @var BackendBaseConfig $config */
             $config = new $configClass($this->getKernel(), $module);
             // set action
             $action = $config->getDefaultAction() !== null ? $config->getDefaultAction() : 'Index';
         } catch (Exception $ex) {
             if (BackendModel::getContainer()->getParameter('kernel.debug')) {
                 throw new Exception('The config file for the module (' . $module . ') can\'t be found.');
             } else {
                 // @todo    don't use redirects for error, we should have something like an invoke method.
                 // build the url
                 $errorUrl = '/' . NAMED_APPLICATION . '/' . $language . '/error?type=action-not-allowed';
                 // add the querystring, it will be processed by the error-handler
                 $errorUrl .= '&querystring=' . rawurlencode('/' . $this->getQueryString());
                 // redirect to the error page
                 $this->redirect($errorUrl, 307);
             }
         }
     }
     // AJAX parameters are passed via GET or POST
     if ($isAJAX) {
         $module = isset($_GET['fork']['module']) ? $_GET['fork']['module'] : '';
         $action = isset($_GET['fork']['action']) ? $_GET['fork']['action'] : '';
         $language = isset($_GET['fork']['language']) ? $_GET['fork']['language'] : SITE_DEFAULT_LANGUAGE;
         $module = isset($_POST['fork']['module']) ? $_POST['fork']['module'] : $module;
         $action = isset($_POST['fork']['action']) ? $_POST['fork']['action'] : $action;
         $language = isset($_POST['fork']['language']) ? $_POST['fork']['language'] : $language;
         $this->setModule($module);
         $this->setAction($action);
         BackendLanguage::setWorkingLanguage($language);
     } else {
         $this->processRegularRequest($module, $action, $language);
     }
 }
Example #12
0
    /**
     * Get templates
     *
     * @param string[optional] $theme The theme we want to fetch the templates from.
     * @return array
     */
    public static function getTemplates($theme = null)
    {
        // get db
        $db = BackendModel::getDB();
        // validate input
        $theme = SpoonFilter::getValue((string) $theme, null, BackendModel::getModuleSetting('core', 'theme', 'core'));
        // get templates
        $templates = (array) $db->getRecords('SELECT i.id, i.label, i.path, i.data
												FROM themes_templates AS i
												WHERE i.theme = ? AND i.active = ?
												ORDER BY i.label ASC', array($theme, 'Y'), 'id');
        // get extras
        $extras = (array) self::getExtras();
        // init var
        $half = (int) ceil(count($templates) / 2);
        $i = 0;
        // loop templates to unserialize the data
        foreach ($templates as $key => &$row) {
            // unserialize
            $row['data'] = unserialize($row['data']);
            $row['has_block'] = false;
            // reset
            if (isset($row['data']['default_extras_' . BL::getWorkingLanguage()])) {
                $row['data']['default_extras'] = $row['data']['default_extras_' . BL::getWorkingLanguage()];
            }
            // any extras?
            if (isset($row['data']['default_extras'])) {
                // loop extras
                foreach ($row['data']['default_extras'] as $value) {
                    // store if the module has blocks
                    if (SpoonFilter::isInteger($value) && isset($extras[$value]) && $extras[$value]['type'] == 'block') {
                        $row['has_block'] = true;
                    }
                }
            }
            // validate
            if (!isset($row['data']['format'])) {
                throw new BackendException('Invalid template-format.');
            }
            // build template HTML
            $row['html'] = self::buildTemplateHTML($row['data']['format']);
            $row['htmlLarge'] = self::buildTemplateHTML($row['data']['format'], true);
            // add all data as json
            $row['json'] = json_encode($row);
            // add the break-element so the templates can be split in 2 columns in the templatechooser
            if ($i == $half) {
                $row['break'] = true;
            }
            // increment
            $i++;
        }
        return (array) $templates;
    }
Example #13
0
 /**
  * Inserts a record into the mailmotor_campaignmonitor_ids table
  *
  * @param string $type    The type of the record.
  * @param string $id      The id in CampaignMonitor.
  * @param string $otherId The id in our tables.
  * @return string
  */
 public static function insertCampaignMonitorID($type, $id, $otherId)
 {
     $type = \SpoonFilter::getValue($type, array('campaign', 'list', 'template'), '');
     if ($type == '') {
         throw new \CampaignMonitorException('No valid CM ID type given (only campaign, list, template).');
     }
     BackendModel::getContainer()->get('database')->insert('mailmotor_campaignmonitor_ids', array('type' => $type, 'cm_id' => $id, 'other_id' => $otherId));
 }
Example #14
0
 /**
  * Get a preview URL to the specific mailing
  *
  * @param int        $id          The id of the mailing.
  * @param string $contentType The content-type to set.
  * @param bool   $forCM       Will this URL be used in Campaign Monitor?
  * @return string
  */
 public static function getMailingPreviewURL($id, $contentType = 'html', $forCM = false)
 {
     // check input
     $contentType = \SpoonFilter::getValue($contentType, array('html', 'plain'), 'html');
     $forCM = \SpoonFilter::getValue($forCM, array(false, true), false, 'int');
     // return the URL
     return SITE_URL . FrontendNavigation::getURLForBlock('Mailmotor', 'Detail') . '/' . $id . '?type=' . $contentType . ($forCM == 1 ? '&cm=' . $forCM : '');
 }
Example #15
0
 /**
  * Fetch the time ago as a language dependant sentence.
  *
  * @return	string							String containing a sentence like 'x minutes ago'
  * @param	int $timestamp					Timestamp you want to make a sentence of.
  * @param	string[optional] $language		Language to use, check SpoonLocale::getAvailableLanguages().
  * @param	string[optional] $format		The format to return if the time passed is greather then a week.
  */
 public static function getTimeAgo($timestamp, $language = 'en', $format = null)
 {
     // init vars
     $timestamp = (int) $timestamp;
     $language = SpoonFilter::getValue($language, SpoonLocale::getAvailableLanguages(), 'en', 'string');
     $locale = array();
     // fetch language
     if (!isset(self::$locales[$language])) {
         require 'spoon/locale/data/' . $language . '.php';
         self::$locales[$language] = $locale;
     }
     $locale = self::$locales[$language];
     // get seconds between given timestamp and current timestamp
     $secondsBetween = time() - $timestamp;
     // calculate years ago
     $yearsAgo = floor($secondsBetween / (365.242199 * 24 * 60 * 60));
     if ($yearsAgo > 1 && $format === null) {
         return sprintf($locale['time']['YearsAgo'], $yearsAgo);
     }
     if ($yearsAgo == 1 && $format === null) {
         return $locale['time']['YearAgo'];
     }
     if ($yearsAgo >= 1 && $format !== null) {
         return self::getDate($format, $timestamp, $language);
     }
     // calculate months ago
     $monthsAgo = floor($secondsBetween / (365.242199 / 12 * 24 * 60 * 60));
     if ($monthsAgo > 1 && $format === null) {
         return sprintf($locale['time']['MonthsAgo'], $monthsAgo);
     }
     if ($monthsAgo == 1 && $format === null) {
         return $locale['time']['MonthAgo'];
     }
     if ($monthsAgo >= 1 && $format !== null) {
         return self::getDate($format, $timestamp, $language);
     }
     // calculate weeks ago
     $weeksAgo = floor($secondsBetween / (7 * 24 * 60 * 60));
     if ($weeksAgo > 1 && $format === null) {
         return sprintf($locale['time']['WeeksAgo'], $weeksAgo);
     }
     if ($weeksAgo == 1 && $format === null) {
         return $locale['time']['WeekAgo'];
     }
     if ($weeksAgo >= 1 && $format !== null) {
         return self::getDate($format, $timestamp, $language);
     }
     // calculate days ago
     $daysAgo = floor($secondsBetween / (24 * 60 * 60));
     if ($daysAgo > 1) {
         return sprintf($locale['time']['DaysAgo'], $daysAgo);
     }
     if ($daysAgo == 1) {
         return $locale['time']['DayAgo'];
     }
     // calculate hours ago
     $hoursAgo = floor($secondsBetween / (60 * 60));
     if ($hoursAgo > 1) {
         return sprintf($locale['time']['HoursAgo'], $hoursAgo);
     }
     if ($hoursAgo == 1) {
         return $locale['time']['HourAgo'];
     }
     // calculate minutes ago
     $minutesAgo = floor($secondsBetween / 60);
     if ($minutesAgo > 1) {
         return sprintf($locale['time']['MinutesAgo'], $minutesAgo);
     }
     if ($minutesAgo == 1) {
         return $locale['time']['MinuteAgo'];
     }
     // calculate seconds ago
     $secondsAgo = floor($secondsBetween);
     if ($secondsAgo > 1) {
         return sprintf($locale['time']['SecondsAgo'], $secondsAgo);
     }
     if ($secondsAgo <= 1) {
         return $locale['time']['SecondAgo'];
     }
 }
Example #16
0
    /**
     * Get tags for an item
     *
     * @param string $module The module wherin will be searched.
     * @param int $otherId The id of the record.
     * @param string[optional] $type The type of the returnvalue, possible values are: array, string (tags will be joined by ,).
     * @param string[optional] $language The language to use, of not provided the working language will be used.
     * @return mixed
     */
    public static function getTags($module, $otherId, $type = 'string', $language = null)
    {
        $module = (string) $module;
        $otherId = (int) $otherId;
        $type = (string) SpoonFilter::getValue($type, array('string', 'array'), 'string');
        $language = $language != null ? (string) $language : BackendLanguage::getWorkingLanguage();
        // fetch tags
        $tags = (array) BackendModel::getDB()->getColumn('SELECT i.tag
			 FROM tags AS i
			 INNER JOIN modules_tags AS mt ON i.id = mt.tag_id
			 WHERE mt.module = ? AND mt.other_id = ? AND i.language = ?
			 ORDER BY i.tag ASC', array($module, $otherId, $language));
        // return as an imploded string
        if ($type == 'string') {
            return implode(',', $tags);
        }
        // return as array
        return $tags;
    }
Example #17
0
 /**
  * Sets the value to sort.
  *
  * @return	void
  * @param	string[optional] $value
  */
 public function setSortParameter($value = 'desc')
 {
     $this->sortParameter = SpoonFilter::getValue($value, array('asc', 'desc'), 'asc');
 }
Example #18
0
 /**
  * Sets the email priority level.
  *
  * @param	int[optional] $level	The e-mail's priority level (1-5, where 1 is not urgent).
  */
 public function setPriority($level = 3)
 {
     // check input
     if (!SpoonFilter::isInteger($level) || !SpoonFilter::getValue($level, range(1, 5, 1), 3, 'int')) {
         throw new SpoonEmailException('No valid priority level given, integer from 1 to 5 required.');
     }
     // store priority level
     $this->priority = $level;
 }
Example #19
0
 /**
  * Initializes the entire API; extract class+method from the request, call, and output.
  *
  * This method exists because the service container needs to be set before
  * the rest of API functionality gets loaded.
  */
 public function initialize()
 {
     self::$content = null;
     /**
      * @var Request
      */
     $request = $this->getContainer()->get('request');
     // simulate $_REQUEST
     $parameters = array_merge((array) $request->query->all(), (array) $request->request->all());
     $method = $request->get('method');
     if ($method == '') {
         return self::output(self::BAD_REQUEST, array('message' => 'No method-parameter provided.'));
     }
     // process method
     $chunks = (array) explode('.', $method, 2);
     // validate method
     if (!isset($chunks[1])) {
         return self::output(self::BAD_REQUEST, array('message' => 'Invalid method.'));
     }
     // camelcase module name
     $chunks[0] = \SpoonFilter::toCamelCase($chunks[0]);
     // build the path to the backend API file
     if ($chunks[0] == 'Core') {
         $class = 'Backend\\Core\\Engine\\Api';
     } else {
         $class = 'Backend\\Modules\\' . $chunks[0] . '\\Engine\\Api';
     }
     // check if the file is present? If it isn't present there is a problem
     if (!class_exists($class)) {
         return self::output(self::BAD_REQUEST, array('message' => 'Invalid method.'));
     }
     // build config-object-name
     $methodName = \SpoonFilter::toCamelCase($chunks[1], '.', true);
     // validate if the method exists
     if (!is_callable(array($class, $methodName))) {
         return self::output(self::BAD_REQUEST, array('message' => 'Invalid method.'));
     }
     // call the method
     try {
         // init var
         $arguments = null;
         // create reflection method
         $reflectionMethod = new \ReflectionMethod($class, $methodName);
         $parameterDocumentation = array();
         // get data from docs
         $matches = array();
         preg_match_all('/@param[\\s\\t]+(.*)[\\s\\t]+\\$(.*)[\\s\\t]+(.*)$/Um', $reflectionMethod->getDocComment(), $matches);
         // documentation found
         if (!empty($matches[0])) {
             // loop matches
             foreach ($matches[0] as $i => $row) {
                 // set documentation
                 $parameterDocumentation[$matches[2][$i]] = array('type' => $matches[1][$i], 'optional' => substr_count($matches[1][$i], '[optional]') > 0, 'description' => $matches[3][$i]);
             }
         }
         // loop parameters
         foreach ($reflectionMethod->getParameters() as $parameter) {
             // init var
             $name = $parameter->getName();
             // check if the parameter is available
             if (!$parameter->isOptional() && !isset($parameters[$name])) {
                 return self::output(self::BAD_REQUEST, array('message' => 'No ' . $name . '-parameter provided.'));
             }
             // add not-passed arguments
             if ($parameter->isOptional() && !isset($parameters[$name])) {
                 $arguments[] = $parameter->getDefaultValue();
             } elseif (isset($parameterDocumentation[$name]['type'])) {
                 // add argument if we know the type
                 // get default value
                 $defaultValue = null;
                 if ($parameter->isOptional()) {
                     $defaultValue = $parameter->getDefaultValue();
                 }
                 // add argument
                 $arguments[] = \SpoonFilter::getValue($parameters[$name], null, $defaultValue, $parameterDocumentation[$name]['type']);
             } else {
                 // fallback
                 $arguments[] = $parameters[$name];
             }
         }
         // get the return
         $data = (array) call_user_func_array(array($class, $methodName), (array) $arguments);
         // output
         if (self::$content === null) {
             self::output(self::OK, $data);
         }
     } catch (\Exception $e) {
         // if we are debugging we should see the exceptions
         if ($this->getContainer()->getParameter('kernel.debug')) {
             if (isset($parameters['debug']) && $parameters['debug'] == 'false') {
                 // do nothing
             } else {
                 throw $e;
             }
         }
         // output
         return self::output(500, array('message' => $e->getMessage()));
     }
 }
Example #20
0
 /**
  * Get a preview URL to the specific mailing
  *
  * @param int $id The id of the mailing.
  * @param string[optional] $contentType The content-type, possible values are: html, plain.
  * @param bool[optional] $forCM Is the URL intended for Campaign Monitor.
  * @return string
  */
 public static function getMailingPreviewURL($id, $contentType = 'html', $forCM = false)
 {
     $contentType = SpoonFilter::getValue($contentType, array('html', 'plain'), 'html');
     $forCM = SpoonFilter::getValue($forCM, array(false, true), false, 'int');
     // return the URL
     return SITE_URL . BackendModel::getURLForBlock('mailmotor', 'detail') . '/' . $id . '?type=' . $contentType . '&cm=' . $forCM;
 }
Example #21
0
    /**
     * Import a locale XML file.
     *
     * @param SimpleXMLElement $xml The locale XML.
     * @param bool[optional] $overwriteConflicts Should we overwrite when there is a conflict?
     * @param array[optional] $frontendLanguages The frontend languages to install locale for.
     * @param array[optional] $backendLanguages The backend languages to install locale for.
     * @param int[optional] $userId Id of the user these translations should be inserted for.
     * @param int[optional] $date The date the translation has been inserted.
     * @return array The import statistics
     */
    public static function importXML(SimpleXMLElement $xml, $overwriteConflicts = false, $frontendLanguages = null, $backendLanguages = null, $userId = null, $date = null)
    {
        $overwriteConflicts = (bool) $overwriteConflicts;
        $statistics = array('total' => 0, 'imported' => 0);
        // set defaults if necessary
        // we can't simply use these right away, because this function is also calles by the installer, which does not have Backend-functions
        if ($frontendLanguages === null) {
            $frontendLanguages = array_keys(BL::getWorkingLanguages());
        }
        if ($backendLanguages === null) {
            $backendLanguages = array_keys(BL::getInterfaceLanguages());
        }
        if ($userId === null) {
            $userId = BackendAuthentication::getUser()->getUserId();
        }
        if ($date === null) {
            $date = BackendModel::getUTCDate();
        }
        // get database instance (don't use BackendModel::getDB() here because this function will also be called during install)
        $db = Spoon::get('database');
        // possible values
        $possibleApplications = array('frontend', 'backend');
        $possibleModules = (array) $db->getColumn('SELECT m.name FROM modules AS m');
        // types
        $typesShort = (array) $db->getEnumValues('locale', 'type');
        foreach ($typesShort as $type) {
            $possibleTypes[$type] = self::getTypeName($type);
        }
        // install English translations anyhow, they're fallback
        $possibleLanguages = array('frontend' => array_unique(array_merge(array('en'), $frontendLanguages)), 'backend' => array_unique(array_merge(array('en'), $backendLanguages)));
        // current locale items (used to check for conflicts)
        $currentLocale = (array) $db->getColumn('SELECT CONCAT(application, module, type, language, name)
			 FROM locale');
        // applications
        foreach ($xml as $application => $modules) {
            // application does not exist
            if (!in_array($application, $possibleApplications)) {
                continue;
            }
            // modules
            foreach ($modules as $module => $items) {
                // module does not exist
                if (!in_array($module, $possibleModules)) {
                    continue;
                }
                // items
                foreach ($items as $item) {
                    // attributes
                    $attributes = $item->attributes();
                    $type = SpoonFilter::getValue($attributes['type'], $possibleTypes, '');
                    $name = SpoonFilter::getValue($attributes['name'], null, '');
                    // missing attributes
                    if ($type == '' || $name == '') {
                        continue;
                    }
                    // real type (shortened)
                    $type = array_search($type, $possibleTypes);
                    // translations
                    foreach ($item->translation as $translation) {
                        // statistics
                        $statistics['total']++;
                        // attributes
                        $attributes = $translation->attributes();
                        $language = SpoonFilter::getValue($attributes['language'], $possibleLanguages[$application], '');
                        // language does not exist
                        if ($language == '') {
                            continue;
                        }
                        // the actual translation
                        $translation = (string) $translation;
                        // locale item
                        $locale['user_id'] = $userId;
                        $locale['language'] = $language;
                        $locale['application'] = $application;
                        $locale['module'] = $module;
                        $locale['type'] = $type;
                        $locale['name'] = $name;
                        $locale['value'] = $translation;
                        $locale['edited_on'] = $date;
                        // found a conflict, overwrite it with the imported translation
                        if ($overwriteConflicts && in_array($application . $module . $type . $language . $name, $currentLocale)) {
                            // statistics
                            $statistics['imported']++;
                            // overwrite
                            $db->update('locale', $locale, 'application = ? AND module = ? AND type = ? AND language = ? AND name = ?', array($application, $module, $type, $language, $name));
                        } elseif (!in_array($application . $module . $type . $language . $name, $currentLocale)) {
                            // statistics
                            $statistics['imported']++;
                            // insert
                            $db->insert('locale', $locale);
                        }
                    }
                }
            }
        }
        // rebuild cache
        foreach ($possibleApplications as $application) {
            foreach ($possibleLanguages[$application] as $language) {
                self::buildCache($language, $application);
            }
        }
        return $statistics;
    }
Example #22
0
 /**
  * Move a page
  *
  * @param int    $id         The id for the page that has to be moved.
  * @param int    $droppedOn  The id for the page where to page has been dropped on.
  * @param string $typeOfDrop The type of drop, possible values are: before, after, inside.
  * @param string $tree       The tree the item is dropped on, possible values are: main, meta, footer, root.
  * @param string $language   The language to use, if not provided we will use the working language.
  *
  * @return bool
  */
 public static function move($id, $droppedOn, $typeOfDrop, $tree, $language = null)
 {
     $id = (int) $id;
     $droppedOn = (int) $droppedOn;
     $typeOfDrop = \SpoonFilter::getValue($typeOfDrop, array('before', 'after', 'inside'), 'inside');
     $tree = \SpoonFilter::getValue($tree, array('main', 'meta', 'footer', 'root'), 'inside');
     $language = $language === null ? BL::getWorkingLanguage() : (string) $language;
     // get db
     $db = BackendModel::getContainer()->get('database');
     // reset type of drop for special pages
     if ($droppedOn == 1) {
         $typeOfDrop = 'inside';
     }
     if ($droppedOn == 0) {
         $typeOfDrop = 'inside';
     }
     // get data for pages
     $page = self::get($id, null, $language);
     $droppedOnPage = self::get($droppedOn, null, $language);
     // reset if the drop was on 0 (new meta)
     if ($droppedOn == 0) {
         $droppedOnPage = self::get(1, null, $language);
     }
     // validate
     if (empty($page) || empty($droppedOnPage)) {
         return false;
     }
     // calculate new parent for items that should be moved inside
     if ($droppedOn == 0) {
         $newParent = 0;
     } elseif ($typeOfDrop == 'inside') {
         // check if item allows children
         if ($droppedOnPage['allow_children'] != 'Y') {
             return false;
         }
         // set new parent to the dropped on page.
         $newParent = $droppedOnPage['id'];
     } else {
         // if the item has to be moved before or after
         $newParent = $droppedOnPage['parent_id'];
     }
     // decide new type
     if ($droppedOn == 0) {
         if ($tree == 'footer') {
             $newType = 'footer';
         } else {
             $newType = 'meta';
         }
     } elseif ($newParent == 0) {
         $newType = $droppedOnPage['type'];
     } else {
         $newType = 'page';
     }
     // calculate new sequence for items that should be moved inside
     if ($typeOfDrop == 'inside') {
         // get highest sequence + 1
         $newSequence = (int) $db->getVar('SELECT MAX(i.sequence)
              FROM pages AS i
              WHERE i.id = ? AND i.language = ? AND i.status = ?', array($newParent, $language, 'active')) + 1;
         // update
         $db->update('pages', array('parent_id' => $newParent, 'sequence' => $newSequence, 'type' => $newType), 'id = ? AND language = ? AND status = ?', array($id, $language, 'active'));
     } elseif ($typeOfDrop == 'before') {
         // calculate new sequence for items that should be moved before
         // get new sequence
         $newSequence = (int) $db->getVar('SELECT i.sequence
              FROM pages AS i
              WHERE i.id = ? AND i.language = ? AND i.status = ?
              LIMIT 1', array($droppedOnPage['id'], $language, 'active')) - 1;
         // increment all pages with a sequence that is higher or equal to the current sequence;
         $db->execute('UPDATE pages
              SET sequence = sequence + 1
              WHERE parent_id = ? AND language = ? AND sequence >= ?', array($newParent, $language, $newSequence + 1));
         // update
         $db->update('pages', array('parent_id' => $newParent, 'sequence' => $newSequence, 'type' => $newType), 'id = ? AND language = ? AND status = ?', array($id, $language, 'active'));
     } elseif ($typeOfDrop == 'after') {
         // calculate new sequence for items that should be moved after
         // get new sequence
         $newSequence = (int) $db->getVar('SELECT i.sequence
             FROM pages AS i
             WHERE i.id = ? AND i.language = ? AND i.status = ?
             LIMIT 1', array($droppedOnPage['id'], $language, 'active')) + 1;
         // increment all pages with a sequence that is higher then the current sequence;
         $db->execute('UPDATE pages
              SET sequence = sequence + 1
              WHERE parent_id = ? AND language = ? AND sequence > ?', array($newParent, $language, $newSequence));
         // update
         $db->update('pages', array('parent_id' => $newParent, 'sequence' => $newSequence, 'type' => $newType), 'id = ? AND language = ? AND status = ?', array($id, $language, 'active'));
     } else {
         return false;
     }
     // get current URL
     $currentURL = (string) $db->getVar('SELECT url
          FROM meta AS m
          WHERE m.id = ?', array($page['meta_id']));
     // rebuild url
     $newURL = self::getURL($currentURL, $id, $newParent, isset($page['data']['is_action']) && $page['data']['is_action'] == 'Y');
     // store
     $db->update('meta', array('url' => $newURL), 'id = ?', array($page['meta_id']));
     // return
     return true;
 }
Example #23
0
 /**
  * Set the form method.
  *
  * @return	SpoonForm
  * @param	string[optional] $method	The method to use, possible values are: get, post.
  */
 public function setMethod($method = 'post')
 {
     $this->method = SpoonFilter::getValue((string) $method, array('get', 'post'), 'post');
     return $this;
 }
Example #24
0
 /**
  * Import a locale XML file.
  *
  * @return	array								Import statistics.
  * @param	SimpleXMLElement $xml				The locale XML.
  * @param	bool[optional] $overwriteConflicts	Should we overwrite when there is a conflict?
  */
 public static function importXML(SimpleXMLElement $xml, $overwriteConflicts = false)
 {
     // init
     $overwriteConflicts = (bool) $overwriteConflicts;
     $statistics = array('total' => 0, 'imported' => 0);
     // possible values
     $possibleApplications = array('frontend', 'backend');
     $possibleModules = BackendModel::getModules(false);
     $possibleLanguages = array('frontend' => array_keys(BL::getWorkingLanguages()), 'backend' => array_keys(BL::getInterfaceLanguages()));
     $possibleTypes = array();
     // types
     $typesShort = (array) BackendModel::getDB()->getEnumValues('locale', 'type');
     foreach ($typesShort as $type) {
         $possibleTypes[$type] = self::getTypeName($type);
     }
     // current locale items (used to check for conflicts)
     $currentLocale = (array) BackendModel::getDB()->getColumn('SELECT CONCAT(application, module, type, language, name) FROM locale');
     // applications
     foreach ($xml as $application => $modules) {
         // application does not exist
         if (!in_array($application, $possibleApplications)) {
             continue;
         }
         // modules
         foreach ($modules as $module => $items) {
             // module does not exist
             if (!in_array($module, $possibleModules)) {
                 continue;
             }
             // items
             foreach ($items as $item) {
                 // attributes
                 $attributes = $item->attributes();
                 $type = SpoonFilter::getValue($attributes['type'], $possibleTypes, '');
                 $name = SpoonFilter::getValue($attributes['name'], null, '');
                 // missing attributes
                 if ($type == '' || $name == '') {
                     continue;
                 }
                 // real type (shortened)
                 $type = array_search($type, $possibleTypes);
                 // translations
                 foreach ($item->translation as $translation) {
                     // statistics
                     $statistics['total']++;
                     // attributes
                     $attributes = $translation->attributes();
                     $language = SpoonFilter::getValue($attributes['language'], $possibleLanguages[$application], '');
                     // language does not exist
                     if ($language == '') {
                         continue;
                     }
                     // the actual translation
                     $translation = (string) $translation;
                     // locale item
                     $locale['user_id'] = BackendAuthentication::getUser()->getUserId();
                     $locale['language'] = $language;
                     $locale['application'] = $application;
                     $locale['module'] = $module;
                     $locale['type'] = $type;
                     $locale['name'] = $name;
                     $locale['value'] = $translation;
                     $locale['edited_on'] = BackendModel::getUTCDate();
                     // found a conflict, overwrite it with the imported translation
                     if ($overwriteConflicts && in_array($application . $module . $type . $language . $name, $currentLocale)) {
                         // statistics
                         $statistics['imported']++;
                         // overwrite
                         BackendModel::getDB(true)->update('locale', $locale, 'application = ? AND module = ? AND type = ? AND language = ? AND name = ?', array($application, $module, $type, $language, $name));
                     } elseif (!in_array($application . $module . $type . $language . $name, $currentLocale)) {
                         // statistics
                         $statistics['imported']++;
                         // insert
                         BackendModel::getDB(true)->insert('locale', $locale);
                     }
                 }
             }
         }
     }
     // rebuild cache
     foreach ($possibleApplications as $application) {
         foreach ($possibleLanguages[$application] as $language) {
             self::buildCache($language, $application);
         }
     }
     // return statistics
     return $statistics;
 }
Example #25
0
 /**
  * Default constructor
  *
  * @return	void
  */
 public function __construct()
 {
     // simulate $_REQUEST
     $parameters = array_merge($_GET, $_POST);
     // validate parameters
     if (!isset($parameters['method'])) {
         self::output(self::BAD_REQUEST, array('message' => 'No method-parameter provided.'));
     }
     // check GET
     $method = SpoonFilter::getValue($parameters['method'], null, '');
     // validate
     if ($method == '') {
         self::output(self::BAD_REQUEST, array('message' => 'No method-parameter provided.'));
     }
     // process method
     $chunks = (array) explode('.', $method, 2);
     // validate method
     if (!isset($chunks[1])) {
         self::output(self::BAD_REQUEST, array('message' => 'Invalid method.'));
     }
     // build the path to the backend API file
     if ($chunks[0] == 'core') {
         $path = BACKEND_CORE_PATH . '/engine/api.php';
     } else {
         $path = BACKEND_MODULES_PATH . '/' . $chunks[0] . '/engine/api.php';
     }
     // check if the fille is present? If it isn't present there is a problem
     if (!SpoonFile::exists($path)) {
         self::output(self::BAD_REQUEST, array('message' => 'Invalid method.'));
     }
     // build config-object-name
     $className = 'Backend' . SpoonFilter::toCamelCase($chunks[0]) . 'API';
     $methodName = SpoonFilter::toCamelCase($chunks[1], '.', true);
     // require the class
     require_once $path;
     // validate if the method exists
     if (!is_callable(array($className, $methodName))) {
         self::output(self::BAD_REQUEST, array('message' => 'Invalid method.'));
     }
     // call the method
     try {
         // init var
         $arguments = null;
         // create reflection method
         $reflectionMethod = new ReflectionMethod($className, $methodName);
         $parameterDocumentation = array();
         // get data from docs
         $matches = array();
         preg_match_all('/@param[\\s\\t]+(.*)[\\s\\t]+\\$(.*)[\\s\\t]+(.*)$/Um', $reflectionMethod->getDocComment(), $matches);
         // documentation found
         if (!empty($matches[0])) {
             // loop matches
             foreach ($matches[0] as $i => $row) {
                 // set documentation
                 $parameterDocumentation[$matches[2][$i]] = array('type' => str_replace('[optional]', '', $matches[1][$i]), 'optional' => substr_count($matches[1][$i], '[optional]') > 0, 'description' => $matches[3][$i]);
             }
         }
         // loop parameters
         foreach ($reflectionMethod->getParameters() as $parameter) {
             // init var
             $name = $parameter->getName();
             // check if the parameter is available
             if (!$parameter->isOptional() && !isset($parameters[$name])) {
                 self::output(self::BAD_REQUEST, array('message' => 'No ' . $name . '-parameter provided.'));
             }
             // add not-passed arguments
             if ($parameter->isOptional() && !isset($parameters[$name])) {
                 $arguments[] = $parameter->getDefaultValue();
             } elseif (isset($parameterDocumentation[$name]['type'])) {
                 // get default value
                 $defaultValue = null;
                 if ($parameter->isOptional()) {
                     $defaultValue = $parameter->getDefaultValue();
                 }
                 // add argument
                 $arguments[] = SpoonFilter::getValue($parameters[$name], null, $defaultValue, $parameterDocumentation[$name]['type']);
             } else {
                 $arguments[] = $parameters[$name];
             }
         }
         // get the return
         $data = (array) call_user_func_array(array($className, $methodName), (array) $arguments);
         // output
         self::output(self::OK, $data);
     } catch (Exception $e) {
         // if we are debugging we should see the exceptions
         if (SPOON_DEBUG) {
             if (isset($parameters['debug']) && $parameters['debug'] == 'false') {
                 // do nothing
             } else {
                 throw $e;
             }
         }
         // output
         self::output(500, array('message' => $e->getMessage()));
     }
 }
Example #26
0
 /**
  * Get templates
  *
  * @param string $theme The theme we want to fetch the templates from.
  *
  * @return array
  * @throws Exception
  */
 public static function getTemplates($theme = null)
 {
     $db = BackendModel::getContainer()->get('database');
     $theme = \SpoonFilter::getValue((string) $theme, null, BackendModel::get('fork.settings')->get('Core', 'theme', 'Core'));
     $templates = (array) $db->getRecords('SELECT i.id, i.label, i.path, i.data
         FROM themes_templates AS i
         WHERE i.theme = ? AND i.active = ?
         ORDER BY i.label ASC', array($theme, 'Y'), 'id');
     $extras = (array) self::getExtras();
     $half = (int) ceil(count($templates) / 2);
     $i = 0;
     foreach ($templates as &$row) {
         $row['data'] = unserialize($row['data']);
         $row['has_block'] = false;
         // reset
         if (isset($row['data']['default_extras_' . BL::getWorkingLanguage()])) {
             $row['data']['default_extras'] = $row['data']['default_extras_' . BL::getWorkingLanguage()];
         }
         // any extras?
         if (isset($row['data']['default_extras'])) {
             foreach ($row['data']['default_extras'] as $value) {
                 if (\SpoonFilter::isInteger($value) && isset($extras[$value]) && $extras[$value]['type'] == 'block') {
                     $row['has_block'] = true;
                 }
             }
         }
         // validate
         if (!isset($row['data']['format'])) {
             throw new Exception('Invalid template-format.');
         }
         $row['html'] = self::buildTemplateHTML($row['data']['format']);
         $row['htmlLarge'] = self::buildTemplateHTML($row['data']['format'], true);
         $row['json'] = json_encode($row);
         if ($i == $half) {
             $row['break'] = true;
         }
         ++$i;
     }
     return (array) $templates;
 }
Example #27
0
 /**
  * Get a parameter specified by the given index
  * The function will return null if the key is not available
  * By default we will cast the return value into a string, if you want
  * something else specify it by passing the wanted type.
  *
  * @param mixed  $index        The index of the parameter.
  * @param string $type         The return type, possible values are:
  *                             bool, boolean, int, integer, float, double, string, array.
  * @param mixed  $defaultValue The value that should be returned if the key is not available.
  *
  * @return mixed
  */
 public function getParameter($index, $type = 'string', $defaultValue = null)
 {
     // does the index exists and isn't this parameter empty
     if ($this->hasParameter($index)) {
         return \SpoonFilter::getValue($this->parameters[$index], null, null, $type);
     }
     // fallback
     return $defaultValue;
 }
Example #28
0
 /**
  * Sets the default sorting method for this column.
  *
  * @return	void
  * @param	string[optional] $sort
  */
 public function setSortingMethod($sort = 'asc')
 {
     $this->sortingMethod = SpoonFilter::getValue($sort, array('asc', 'desc'), 'asc');
 }
Example #29
0
 /**
  * Adds a date field to the form
  *
  * @param string $name       Name of the element.
  * @param mixed  $value      The value for the element.
  * @param string $type       The type (from, till, range) of the datepicker.
  * @param int    $date       The date to use.
  * @param int    $date2      The second date for a rangepicker.
  * @param string $class      Class(es) that have to be applied on the element.
  * @param string $classError Class(es) that have to be applied when an error occurs on the element.
  * @return FrontendFormDate
  */
 public function addDate($name, $value = null, $type = null, $date = null, $date2 = null, $class = null, $classError = null)
 {
     $name = (string) $name;
     $value = $value !== null ? $value !== '' ? (int) $value : '' : null;
     $type = \SpoonFilter::getValue($type, array('from', 'till', 'range'), 'none');
     $date = $date !== null ? (int) $date : null;
     $date2 = $date2 !== null ? (int) $date2 : null;
     $class = $class !== null ? (string) $class : 'inputText inputDate';
     $classError = $classError !== null ? (string) $classError : 'inputTextError inputDateError';
     // validate
     if ($type == 'from' && ($date == 0 || $date == null)) {
         throw new Exception('A date field with type "from" should have a valid date-parameter.');
     }
     if ($type == 'till' && ($date == 0 || $date == null)) {
         throw new Exception('A date field with type "till" should have a valid date-parameter.');
     }
     if ($type == 'range' && ($date == 0 || $date2 == 0 || $date == null || $date2 == null)) {
         throw new Exception('A date field with type "range" should have 2 valid date-parameters.');
     }
     // set mask and firstday
     $mask = Model::get('fork.settings')->get('Core', 'date_format_short');
     $firstDay = 1;
     // build attributes
     $attributes['data-mask'] = str_replace(array('d', 'm', 'Y', 'j', 'n'), array('dd', 'mm', 'yy', 'd', 'm'), $mask);
     $attributes['data-firstday'] = $firstDay;
     $attributes['year'] = date('Y', $value);
     $attributes['month'] = date('n', $value);
     $attributes['day'] = date('j', $value);
     // add extra classes based on type
     switch ($type) {
         // start date
         case 'from':
             $class .= ' inputDatefieldFrom inputText';
             $classError .= ' inputDatefieldFrom';
             $attributes['data-startdate'] = date('Y-m-d', $date);
             break;
             // end date
         // end date
         case 'till':
             $class .= ' inputDatefieldTill inputText';
             $classError .= ' inputDatefieldTill';
             $attributes['data-enddate'] = date('Y-m-d', $date);
             break;
             // date range
         // date range
         case 'range':
             $class .= ' inputDatefieldRange inputText';
             $classError .= ' inputDatefieldRange';
             $attributes['data-startdate'] = date('Y-m-d', $date);
             $attributes['data-enddate'] = date('Y-m-d', $date2);
             break;
             // normal date field
         // normal date field
         default:
             $class .= ' inputDatefieldNormal inputText';
             $classError .= ' inputDatefieldNormal';
             break;
     }
     // create a datefield
     $this->add(new FrontendFormDate($name, $value, $mask, $class, $classError));
     // set attributes
     parent::getField($name)->setAttributes($attributes);
     // return date field
     return parent::getField($name);
 }
Example #30
0
 /**
  * Set column for the widget
  *
  * @return	void
  * @param	string $column	Possible values are: left, middle, right.
  */
 protected function setColumn($column)
 {
     // allowed values
     $allowedColumns = array('left', 'middle', 'right');
     // redefine
     $this->column = SpoonFilter::getValue((string) $column, $allowedColumns, 'left');
 }