/** * Returns the CampaignMonitor object * * @param int $listId The default list id to use. * @return \CampaignMonitor */ public static function getCM($listId = null) { // campaignmonitor reference exists if (!FrontendModel::getContainer()->has('campaignmonitor')) { // check if the CampaignMonitor class exists if (!file_exists(PATH_LIBRARY . '/external/campaignmonitor.php')) { // the class doesn't exist, so throw an exception throw new FrontendException('The CampaignMonitor wrapper class is not found. Please locate and place it in /library/external'); } // require CampaignMonitor class require_once PATH_LIBRARY . '/external/campaignmonitor.php'; // set login data $url = FrontendModel::get('fork.settings')->get('Mailmotor', 'cm_url'); $username = FrontendModel::get('fork.settings')->get('Mailmotor', 'cm_username'); $password = FrontendModel::get('fork.settings')->get('Mailmotor', 'cm_password'); // init CampaignMonitor object $cm = new \CampaignMonitor($url, $username, $password, 5, self::getClientId()); // set CampaignMonitor object reference FrontendModel::getContainer()->set('campaignmonitor', $cm); // get the default list ID $listId = !empty($listId) ? $listId : self::getDefaultListID(); // set the default list ID $cm->setListId($listId); } // return the CampaignMonitor object return FrontendModel::getContainer()->get('campaignmonitor'); }
/** * Fetches a certain item * * @param string $id * @return array */ public static function get($id) { $item = (array) FrontendModel::get('database')->getRecord('SELECT i.* FROM instagram_users AS i WHERE i.id = ? AND i.hidden = ?', array((int) $id, 'N')); // no results? if (empty($item)) { return array(); } return $item; }
/** * Execute the action */ public function execute() { parent::execute(); // Get POST parameters $userId = \SpoonFilter::getPostValue('userId', null, ''); // Get count settings $this->recentCount = FrontendModel::get('fork.settings')->get('Instagram', 'num_recent_items', 10); // Get the images from the Instagram API $this->images = FrontendInstagramModel::getRecentMedia($userId, $this->recentCount); // Output the result $this->output(self::OK, $this->images); }
/** * @param FormBuilderSubmittedEvent $event */ public function onFormSubmitted(FormBuilderSubmittedEvent $event) { $form = $event->getForm(); // need to send mail if ($form['method'] == 'database_email') { // build our message $from = FrontendModel::get('fork.settings')->get('Core', 'mailer_from'); $fieldData = $this->getEmailFields($event->getData()); $message = \Common\Mailer\Message::newInstance(sprintf(FL::getMessage('FormBuilderSubject'), $form['name']))->parseHtml(FRONTEND_MODULES_PATH . '/FormBuilder/Layout/Templates/Mails/Form.tpl', array('sentOn' => time(), 'name' => $form['name'], 'fields' => $fieldData), true)->setTo($form['email'])->setFrom(array($from['email'] => $from['name'])); // check if we have a replyTo email set foreach ($form['fields'] as $field) { if (array_key_exists('reply_to', $field['settings']) && $field['settings']['reply_to'] === true) { $email = $fieldData[$field['id']]['value']; $message->setReplyTo(array($email => $email)); } } if ($message->getReplyTo() === null) { $replyTo = FrontendModel::get('fork.settings')->get('Core', 'mailer_reply_to'); $message->setReplyTo(array($replyTo['email'] => $replyTo['name'])); } $this->mailer->send($message); } }
/** * The constructor will store the instance in the reference, preset some settings and map the custom modifiers. */ public function __construct() { parent::__construct(func_get_arg(0), func_get_arg(1), func_get_arg(2)); $this->debugMode = Model::getContainer()->getParameter('kernel.debug'); $this->forkSettings = Model::get('fork.settings'); // fork has been installed if ($this->forkSettings) { $this->themePath = FRONTEND_PATH . '/Themes/' . $this->forkSettings->get('Core', 'theme', 'default'); $loader = $this->environment->getLoader(); $loader = new \Twig_Loader_Chain(array($loader, new \Twig_Loader_Filesystem($this->getLoadingFolders()))); $this->environment->setLoader($loader); // connect symphony forms $formEngine = new TwigRendererEngine($this->getFormTemplates('FormLayout.html.twig')); $formEngine->setEnvironment($this->environment); $this->environment->addExtension(new SymfonyFormExtension(new TwigRenderer($formEngine, Model::get('security.csrf.token_manager')))); } $this->environment->disableStrictVariables(); // init Form extension new FormExtension($this->environment); // start the filters / globals TwigFilters::getFilters($this->environment, 'Frontend'); $this->startGlobals($this->environment); }
/** * The default constructor * * @param string $title The title off the feed. * @param string $link The link of the feed. * @param string $description The description of the feed. * @param array $items An array with SpoonRSSItems. */ public function __construct($title, $link, $description, array $items = array()) { // decode $title = \SpoonFilter::htmlspecialcharsDecode($title); $description = \SpoonFilter::htmlspecialcharsDecode($description); // call the parent parent::__construct($title, Model::addURLParameters($link, array('utm_source' => 'feed', 'utm_medium' => 'rss', 'utm_campaign' => CommonUri::getUrl($title))), $description, $items); $siteTitle = \SpoonFilter::htmlspecialcharsDecode(Model::get('fork.settings')->get('Core', 'site_title_' . LANGUAGE)); // set feed properties $this->setLanguage(LANGUAGE); $this->setCopyright(\SpoonDate::getDate('Y') . ' ' . $siteTitle); $this->setGenerator($siteTitle); $this->setImage(SITE_URL . FRONTEND_CORE_URL . '/Layout/images/rss_image.png', $title, $link); // theme was set if (Model::get('fork.settings')->get('Core', 'theme', null) != null) { // theme name $theme = Model::get('fork.settings')->get('Core', 'theme', null); // theme rss image exists if (is_file(PATH_WWW . '/src/Frontend/Themes/' . $theme . '/Core/images/rss_image.png')) { // set rss image $this->setImage(SITE_URL . '/src/Frontend/Themes/' . $theme . '/Core/images/rss_image.png', $title, $link); } } }
/** * Formats a timestamp as a string that indicates the time ago * syntax: {$var|timeago} * * @param string $var A UNIX-timestamp that will be formatted as a time-ago-string. * @return string */ public static function timeAgo($var = null) { $var = (int) $var; // invalid timestamp if ($var == 0) { return ''; } // return return '<abbr title="' . \SpoonDate::getDate(Model::get('fork.settings')->get('Core', 'date_format_long') . ', ' . Model::get('fork.settings')->get('Core', 'time_format'), $var, FRONTEND_LANGUAGE) . '">' . \SpoonDate::getTimeAgo($var, FRONTEND_LANGUAGE) . '</abbr>'; }
/** * Validate the form * * @return void */ private function validateForm() { // is the form submitted if ($this->frm->isSubmitted()) { // validate required fields $email = $this->frm->getField('email'); // validate required fields if ($email->isEmail(FL::err('EmailIsInvalid'))) { if (FrontendModel::get('mailmotor.member')->isSubscribed($email->getValue())) { $email->addError(FL::err('AlreadySubscribed')); } // we need to add this because the line below. // $this->frm->getErrors() only checks if form errors are set, not if an element in the form has errors. } else { $this->frm->addError(FL::err('AlreadySubscribed')); } // no errors? if ($this->frm->isCorrect()) { // build $mergeVars = array(); try { // subscribe the user to our default group FrontendModel::get('mailmotor.member')->subscribe($email->getValue(), null, $mergeVars); // trigger event FrontendModel::triggerEvent('MailMotor', 'after_subscribe', array('email' => $email->getValue())); // redirect $this->redirect(FrontendNavigation::getURLForBlock('MailMotor', 'Subscribe') . '?sent=true#mailMotorSubscribeForm'); } catch (Exception $e) { // when debugging we need to see the exceptions if (\SPOON_DEBUG) { throw $e; } // show error $this->tpl->assign('mailMotorSubscribeHasError', true); } // show errors } else { $this->tpl->assign('mailMotorSubscribeHasFormError', true); } } }
/** * Get the access token from the settings * * @return String Access token */ private static function getAccessToken() { return FrontendModel::get('fork.settings')->get('Instagram', 'access_token'); }
/** * Get navigation HTML * * @param string $type The type of navigation the HTML should be build for. * @param int $parentId The parentID to start of. * @param int $depth The maximum depth to parse. * @param array $excludeIds PageIDs to be excluded. * @param string $template The template that will be used. * @param int $depthCounter A counter that will hold the current depth. * * @return string * @throws Exception */ public static function getNavigationHTML($type = 'page', $parentId = 0, $depth = null, $excludeIds = array(), $template = '/Core/Layout/Templates/Navigation.html.twig', $depthCounter = 1) { // get navigation $navigation = self::getNavigation(); // merge the exclude ids with the previously set exclude ids $excludeIds = array_merge((array) $excludeIds, self::$excludedPageIds); // meta-navigation is requested but meta isn't enabled if ($type == 'meta' && (!Model::get('fork.settings')->get('Pages', 'meta_navigation', true) || !isset($navigation['meta']))) { return ''; } // validate if (!isset($navigation[$type])) { throw new Exception('This type (' . $type . ') isn\'t a valid navigation type. Possible values are: page, footer, meta.'); } if (!isset($navigation[$type][$parentId])) { throw new Exception('The parent (' . $parentId . ') doesn\'t exists.'); } // special construction to merge home with its immediate children $mergedHome = false; while (true) { // loop elements foreach ($navigation[$type][$parentId] as $id => $page) { // home is a special item, it should live on the same depth if ($page['page_id'] == 1 && !$mergedHome) { // extra checks otherwise exceptions will wbe triggered. if (!isset($navigation[$type][$parentId]) || !is_array($navigation[$type][$parentId])) { $navigation[$type][$parentId] = array(); } if (!isset($navigation[$type][$page['page_id']]) || !is_array($navigation[$type][$page['page_id']])) { $navigation[$type][$page['page_id']] = array(); } // add children $navigation[$type][$parentId] = array_merge($navigation[$type][$parentId], $navigation[$type][$page['page_id']]); // mark as merged $mergedHome = true; // restart loop continue 2; } // not hidden and not an action if ($page['hidden'] || $page['tree_type'] == 'direct_action') { unset($navigation[$type][$parentId][$id]); continue; } // authentication if (isset($page['data'])) { // unserialize data $page['data'] = unserialize($page['data']); // if auth_required isset and is true if (isset($page['data']['auth_required']) && $page['data']['auth_required']) { // is profile logged? unset if (!FrontendAuthentication::isLoggedIn()) { unset($navigation[$type][$parentId][$id]); continue; } // check if group auth is set if (!empty($page['data']['auth_groups'])) { $inGroup = false; // loop group and set value true if one is found foreach ($page['data']['auth_groups'] as $group) { if (FrontendAuthentication::getProfile()->isInGroup($group)) { $inGroup = true; } } // unset page if not in any of the groups if (!$inGroup) { unset($navigation[$type][$parentId][$id]); } } } } // some ids should be excluded if (in_array($page['page_id'], (array) $excludeIds)) { unset($navigation[$type][$parentId][$id]); continue; } // if the item is in the selected page it should get an selected class if (in_array($page['page_id'], self::$selectedPageIds)) { $navigation[$type][$parentId][$id]['selected'] = true; } else { $navigation[$type][$parentId][$id]['selected'] = false; } // add nofollow attribute if needed if ($page['no_follow']) { $navigation[$type][$parentId][$id]['nofollow'] = true; } else { $navigation[$type][$parentId][$id]['nofollow'] = false; } // meta and footer subpages have the "page" type if ($type == 'meta' || $type == 'footer') { $subType = 'page'; } else { $subType = $type; } // fetch children if needed if (isset($navigation[$subType][$page['page_id']]) && $page['page_id'] != 1 && ($depth == null || $depthCounter + 1 <= $depth)) { $navigation[$type][$parentId][$id]['children'] = self::getNavigationHTML($subType, $page['page_id'], $depth, $excludeIds, $template, $depthCounter + 1); } else { $navigation[$type][$parentId][$id]['children'] = false; } // add parent id $navigation[$type][$parentId][$id]['parent_id'] = $parentId; // add depth $navigation[$type][$parentId][$id]['depth'] = $depthCounter; // set link $navigation[$type][$parentId][$id]['link'] = static::getURL($page['page_id']); // is this an internal redirect? if (isset($page['redirect_page_id']) && $page['redirect_page_id'] != '') { $navigation[$type][$parentId][$id]['link'] = static::getURL((int) $page['redirect_page_id']); } // is this an external redirect? if (isset($page['redirect_url']) && $page['redirect_url'] != '') { $navigation[$type][$parentId][$id]['link'] = $page['redirect_url']; } } // break the loop (it is only used for the special construction with home) break; } // return parsed content return Model::get('templating')->render($template, array('navigation' => $navigation[$type][$parentId])); }
/** * Returns the content from a given template * * @param string $template The template to use. * @param array $variables The variables to assign. * * @return string */ private function getTemplateContent($template, $variables = null) { // with the strpos we check if it is a frontend template, in that case we use the frontend template to prevent // errors that the template could not be found. This way we don't have a backwards compatibility break. if (APPLICATION !== 'Backend' || strpos($template, FRONTEND_CORE_PATH) !== false) { return Model::get('templating')->render($template, $variables); } $tpl = new BackendTemplate(false); // variables were set if (!empty($variables)) { $tpl->assign($variables); } // grab the content return $tpl->getContent($template); }
/** * Get the redirect languages * * @return array */ public static function getRedirectLanguages() { // validate the cache if (empty(self::$languages['possible_redirect'])) { // grab from settings $redirectLanguages = (array) Model::get('fork.settings')->get('Core', 'redirect_languages'); // store in cache self::$languages['possible_redirect'] = $redirectLanguages; } // return return self::$languages['possible_redirect']; }
/** * Search * The actual search will be performed by the execSearch() method. * It will then pass on the results to the specific modules, which are then * responsible for returning the required data and filtering out unwanted * results (entries that should not be shown) * The activation/deactivation of search indices will automatically be * handled by this function to keep the search index up to date, based on * the module's returned results * * This function can be called with either a string as parameter (simple * search) or an array (advanced search) * Simple search: all search index fields will be searched for the given * term * Advanced search: only the given fields (keys in the array) will be * matched to the corresponding values (corresponding values in the array) * * @param string $term The search term (simple search) or the fields to * search for (advanced search - please note that the * field names may not be consistent throughout * several modules). * @param int $limit The number of articles to get. * @param int $offset The offset. * @return array */ public static function search($term, $limit = 20, $offset = 0) { // revalidate searches if (FrontendModel::get('fork.settings')->get('Search', 'validate_search', true) == true) { self::validateSearch(); } // @note: on heavy sites with a lot of inactive search indices better // use a cronjob (which will automatically set this module setting to N) // execute the actual search $searchResults = self::execSearch($term, $limit, $offset); // get the total amount of results (we'll get back to this later ;) ) $total = count($searchResults); // none found? return empty :( if (!$searchResults) { return array(); } // prepare to send to modules $moduleResults = array(); // loop the result set foreach ($searchResults as $searchResult) { $moduleResults[$searchResult['module']][] = $searchResult['other_id']; } // pass the results to the modules foreach ($moduleResults as $module => $otherIds) { // check if this module actually is prepared to handle searches $class = 'Frontend\\Modules\\' . $module . '\\Engine\\Model'; if (is_callable(array($class, 'search'))) { // get the required info from our module $moduleResults[$module] = call_user_func(array($class, 'search'), $otherIds); } else { // does not exist, let's get this module out of here unset($moduleResults[$module]); } } // now place the prepared data back in our original result set, which has our results in correct order foreach ($searchResults as $i => $result) { // loop parsed results for this specific module to find the one we want here foreach ($moduleResults[$result['module']] as $otherId => $moduleResult) { // that's the one.. if ($otherId == $result['other_id']) { $searchResults[$i] = array_merge(array('module' => $result['module']), $moduleResult); continue 2; } } // if we made it here, we obviously did not get this result parsed by the module, so remove it! unset($searchResults[$i]); self::statusIndex($result['module'], (array) $result['other_id'], false); } // results got removed by the module? oh noes :o have another run, // because now we've deactivated those responsible for the holes :) if (count($searchResults) < $total && $total == $limit) { $searchResults = self::search($term, $limit, $offset); } // return results return $searchResults; }
/** * Get avatar * * @param int $id The id for the profile we want to get the avatar from. * @param string $email The email from the user we can use for gravatar. * @param string $size The resolution you want to use. Default: 240x240 pixels. * @return string $avatar The absolute path to the avatar. */ public static function getAvatar($id, $email = null, $size = '240x240') { // redefine id $id = (int) $id; // return avatar from cache if (isset(self::$avatars[$id])) { return self::$avatars[$id]; } // define avatar path $avatarPath = FRONTEND_FILES_URL . '/Profiles/Avatars/' . $size . '/'; // get user $user = self::get($id); // if no email is given if (!$email) { // redefine email $email = $user->getEmail(); } // define avatar $avatar = $user->getSetting('avatar'); // no custom avatar defined, get gravatar if allowed if (empty($avatar) && FrontendModel::get('fork.settings')->get('Profiles', 'allow_gravatar', true)) { // define hash $hash = md5(strtolower(trim('d' . $email))); // define avatar url $avatar = 'http://www.gravatar.com/avatar/' . $hash; // when email not exists, it has to show our custom no-avatar image $avatar .= '?d=' . urlencode(SITE_URL . $avatarPath) . 'no-avatar.gif'; } elseif (empty($avatar)) { // define avatar as not found $avatar = SITE_URL . $avatarPath . 'no-avatar.gif'; } else { // define custom avatar path $avatar = $avatarPath . $avatar; } // set avatar in cache self::$avatars[$id] = $avatar; // return avatar image path return $avatar; }
/** * Formats plain text as HTML, links will be detected, paragraphs will be inserted * syntax: {{ $string|cleanupPlainText }}. * * @param string $string The text to cleanup. * * @return string */ public static function cleanupPlainText($string) { // redefine $string = (string) $string; // detect links $string = \SpoonFilter::replaceURLsWithAnchors($string, FrontendModel::get('fork.settings')->get('Core', 'seo_nofollow_in_comments', false)); // replace newlines $string = str_replace("\r", '', $string); $string = preg_replace('/(?<!.)(\\r\\n|\\r|\\n){3,}$/m', '', $string); // replace br's into p's $string = '<p>' . str_replace("\n", '</p><p>', $string) . '</p>'; // cleanup $string = str_replace("\n", '', $string); $string = str_replace('<p></p>', '', $string); // return return $string; }
/** * Get the number of items in a category * * @param int $categoryId * @return int */ public static function getCategoryCount($categoryId) { return (int) FrontendModel::get('database')->getVar('SELECT COUNT(i.id) AS count FROM blocks AS i WHERE i.category_id = ?', array((int) $categoryId)); }
/** * Notify the admin * * @param array $subscription The subscription that was submitted. */ public static function notifyAdmin(array $subscription) { // don't notify admin in case of spam if ($subscription['status'] == 'spam') { return; } // build data for push notification if ($subscription['status'] == 'moderation') { $key = 'AGENDA_SUBSCRIPTION_MOD'; } else { $key = 'AGENDA_SUBSCRIPTION'; } $name = $subscription['name']; if (mb_strlen($name) > 20) { $name = mb_substr($name, 0, 19) . '…'; } $alert = array('loc-key' => $key, 'loc-args' => array($name)); // build data $data = array('api' => SITE_URL . '/api/1.0', 'id' => $subscription['id']); // push it FrontendModel::pushToAppleApp($alert, null, 'default', $data); // get settings $notifyByMailOnSubscription = FrontendModel::get('fork.settings')->get('Agenda', 'notify_by_email_on_new_subscription', false); $notifyByMailOnSubscription = FrontendModel::get('fork.settings')->get('Agenda', 'notify_by_email_on_new_subscription_to_moderate', false); // create URLs $backendURL = SITE_URL . FrontendNavigation::getBackendURLForBlock('subscriptions', 'agenda') . '#tabModeration'; // notify on all comments if ($notifyByMailOnSubscription) { // init var $message = null; $from = FrontendModel::get('fork.settings')->get('Core', 'mailer_from'); if ($subscription['status'] == 'moderation') { $message = \Common\Mailer\Message::newInstance(FL::msg('NotificationSubject'))->parseHtml(FRONTEND_CORE_PATH . '/Layout/Templates/Mails/Notification.tpl', array('message' => vsprintf(FL::msg('AgendaEmailNotificationsNewSubscriptionToModerate'), array($subscription['name'], $subscription['agenda_title'], $backendURL))), true)->setTo('*****@*****.**')->setFrom(array($from['email'] => $from['name'])); } elseif ($subscription['status'] == 'published') { $message = \Common\Mailer\Message::newInstance(FL::msg('NotificationSubject'))->parseHtml(FRONTEND_CORE_PATH . '/Layout/Templates/Mails/Notification.tpl', array('message' => vsprintf(FL::msg('AgendaEmailNotificationsNewSubscription'), array($subscription['name'], $subscription['agenda_title']))), true)->setTo('*****@*****.**')->setFrom(array($from['email'] => $from['name'])); } FrontendModel::get('mailer')->send($message); // send the mail // FrontendModel::get('mailer')->addEmail( // FL::msg('NotificationSubject'), // FRONTEND_CORE_PATH . '/Layout/Templates/Mails/Notification.tpl', // $variables, // null, // null, // null, // null, // null, // null, // null, // null, // null, // null, // null, // true // ); } elseif ($notifyByMailOnSubscriptionToModerate && $subscription['status'] == 'moderation') { $message = null; $from = FrontendModel::get('fork.settings')->get('Core', 'mailer_from'); $message = \Common\Mailer\Message::newInstance(FL::msg('NotificationSubject'))->parseHtml(FRONTEND_CORE_PATH . '/Layout/Templates/Mails/Notification.tpl', array('message' => vsprintf(FL::msg('AgendaEmailNotificationsNewSubscriptionToModerate'), array($subscription['name'], $subscription['agenda_title'], $backendURL))), true)->setTo('*****@*****.**')->setFrom(array($from['email'] => $from['name'])); FrontendModel::get('mailer')->send($message); // set variables // $variables['message'] = vsprintf(FL::msg('AgendaEmailNotificationsNewSubscriptionToModerate'), // array($subscription['name'], $subscription['agenda_title'], $backendURL)); // // // send the mail // FrontendModel::get('mailer')->addEmail( // FL::msg('NotificationSubject'), // FRONTEND_CORE_PATH . '/Layout/Templates/Mails/Notification.tpl', // $variables, // null, // null, // null, // null, // null, // null, // null, // null, // null, // null, // null, // true // ); } }
/** * Get navigation HTML * * @param string $type The type of navigation the HTML should be build for. * @param int $parentId The parentID to start of. * @param int $depth The maximum depth to parse. * @param array $excludeIds PageIDs to be excluded. * @param string $tpl The template that will be used. * @param int $depthCounter A counter that will hold the current depth. * @return string */ public static function getNavigationHTML($type = 'page', $parentId = 0, $depth = null, $excludeIds = array(), $tpl = '/Core/Layout/Templates/Navigation.tpl', $depthCounter = 1) { // get navigation $navigation = self::getNavigation(); // merge the exclude ids with the previously set exclude ids $excludeIds = array_merge((array) $excludeIds, self::$excludedPageIds); // meta-navigation is requested but meta isn't enabled if ($type == 'meta' && (!Model::get('fork.settings')->get('Pages', 'meta_navigation', true) || !isset($navigation['meta']))) { return ''; } // validate if (!isset($navigation[$type])) { throw new Exception('This type (' . $type . ') isn\'t a valid navigation type. Possible values are: page, footer, meta.'); } if (!isset($navigation[$type][$parentId])) { throw new Exception('The parent (' . $parentId . ') doesn\'t exists.'); } // special construction to merge home with it's immediate children $mergedHome = false; while (true) { // loop elements foreach ($navigation[$type][$parentId] as $id => $page) { // home is a special item, it should live on the same depth if ($page['page_id'] == 1 && !$mergedHome) { // extra checks otherwise exceptions will wbe triggered. if (!isset($navigation[$type][$parentId]) || !is_array($navigation[$type][$parentId])) { $navigation[$type][$parentId] = array(); } if (!isset($navigation[$type][$page['page_id']]) || !is_array($navigation[$type][$page['page_id']])) { $navigation[$type][$page['page_id']] = array(); } // add children $navigation[$type][$parentId] = array_merge($navigation[$type][$parentId], $navigation[$type][$page['page_id']]); // mark as merged $mergedHome = true; // restart loop continue 2; } // not hidden and not an action if ($page['hidden'] || $page['tree_type'] == 'direct_action') { unset($navigation[$type][$parentId][$id]); continue; } // some ids should be excluded if (in_array($page['page_id'], (array) $excludeIds)) { unset($navigation[$type][$parentId][$id]); continue; } // if the item is in the selected page it should get an selected class if (in_array($page['page_id'], self::$selectedPageIds)) { $navigation[$type][$parentId][$id]['selected'] = true; } else { $navigation[$type][$parentId][$id]['selected'] = false; } // add nofollow attribute if needed if ($page['no_follow']) { $navigation[$type][$parentId][$id]['nofollow'] = true; } else { $navigation[$type][$parentId][$id]['nofollow'] = false; } // meta and footer subpages have the "page" type if ($type == 'meta' || $type == "footer") { $subType = 'page'; } else { $subType = $type; } // fetch children if needed if (isset($navigation[$subType][$page['page_id']]) && $page['page_id'] != 1 && ($depth == null || $depthCounter + 1 <= $depth)) { $navigation[$type][$parentId][$id]['children'] = self::getNavigationHTML($subType, $page['page_id'], $depth, $excludeIds, $tpl, $depthCounter + 1); } else { $navigation[$type][$parentId][$id]['children'] = false; } // add parent id $navigation[$type][$parentId][$id]['parent_id'] = $parentId; // add depth $navigation[$type][$parentId][$id]['depth'] = $depthCounter; // set link $navigation[$type][$parentId][$id]['link'] = static::getURL($page['page_id']); // is this an internal redirect? if (isset($page['redirect_page_id']) && $page['redirect_page_id'] != '') { $navigation[$type][$parentId][$id]['link'] = static::getURL((int) $page['redirect_page_id']); } // is this an external redirect? if (isset($page['redirect_url']) && $page['redirect_url'] != '') { $navigation[$type][$parentId][$id]['link'] = $page['redirect_url']; } } // break the loop (it is only used for the special construction with home) break; } // create template $navigationTpl = new Template(false); // assign navigation to template $navigationTpl->assign('navigation', $navigation[$type][$parentId]); // return parsed content return $navigationTpl->getContent(FRONTEND_PATH . (string) $tpl, true, true); }
/** * Validate the form * * @return void */ private function validateForm() { // is the form submitted if ($this->frm->isSubmitted()) { // get values $email = $this->frm->getField('email'); // validate required fields if ($email->isEmail(FL::err('EmailIsInvalid'))) { // email does not exist if (!FrontendModel::get('mailmotor.member')->exists($email->getValue())) { $email->addError(FL::err('EmailNotInDatabase')); } // user is already unsubscribed if (FrontendModel::get('mailmotor.member')->isUnsubscribed($email->getValue())) { $email->addError(FL::err('AlreadyUnsubscribed')); } } // no errors and email address does not exist if ($this->frm->isCorrect()) { try { // unsubscribe the user FrontendModel::get('mailmotor.member')->unsubscribe($email->getValue()); // trigger event FrontendModel::triggerEvent('MailMotor', 'after_unsubscribe', array('email' => $email->getValue())); // redirect $this->redirect(FrontendNavigation::getURLForBlock('MailMotor', 'Unsubscribe') . '?sent=true#unsubscribeForm'); } catch (Exception $e) { // show error $this->tpl->assign('mailMotorUnsubscribeHasError', true); } // show errors } else { $this->tpl->assign('mailMotorUnsubscribeHasFormError', true); } } }
/** * Returns the client ID from the settings * * @return string */ public static function getClientID() { return (string) FrontendModel::get('fork.settings')->get('Mailmotor', 'cm_client_id'); }
/** * Notify the admin * * @param array $comment The comment that was submitted. */ public static function notifyAdmin(array $comment) { // don't notify admin in case of spam if ($comment['status'] == 'spam') { return; } // get settings $notifyByMailOnComment = FrontendModel::get('fork.settings')->get('Blog', 'notify_by_email_on_new_comment', false); $notifyByMailOnCommentToModerate = FrontendModel::get('fork.settings')->get('Blog', 'notify_by_email_on_new_comment_to_moderate', false); // create URLs $url = SITE_URL . FrontendNavigation::getURLForBlock('Blog', 'Detail') . '/' . $comment['post_url'] . '#comment-' . $comment['id']; $backendURL = SITE_URL . FrontendNavigation::getBackendURLForBlock('comments', 'Blog') . '#tabModeration'; // notify on all comments if ($notifyByMailOnComment) { // init var $variables = null; // comment to moderate if ($comment['status'] == 'moderation') { $variables['message'] = vsprintf(FL::msg('BlogEmailNotificationsNewCommentToModerate'), array($comment['author'], $url, $comment['post_title'], $backendURL)); } elseif ($comment['status'] == 'published') { // comment was published $variables['message'] = vsprintf(FL::msg('BlogEmailNotificationsNewComment'), array($comment['author'], $url, $comment['post_title'])); } $to = FrontendModel::get('fork.settings')->get('Core', 'mailer_to'); $from = FrontendModel::get('fork.settings')->get('Core', 'mailer_from'); $replyTo = FrontendModel::get('fork.settings')->get('Core', 'mailer_reply_to'); $message = Message::newInstance(FL::msg('NotificationSubject'))->setFrom(array($from['email'] => $from['name']))->setTo(array($to['email'] => $to['name']))->setReplyTo(array($replyTo['email'] => $replyTo['name']))->parseHtml('/Core/Layout/Templates/Mails/Notification.html.twig', $variables, true); FrontendModel::get('mailer')->send($message); } elseif ($notifyByMailOnCommentToModerate && $comment['status'] == 'moderation') { // only notify on new comments to moderate and if the comment is one to moderate // set variables $variables['message'] = vsprintf(FL::msg('BlogEmailNotificationsNewCommentToModerate'), array($comment['author'], $url, $comment['post_title'], $backendURL)); $to = FrontendModel::get('fork.settings')->get('Core', 'mailer_to'); $from = FrontendModel::get('fork.settings')->get('Core', 'mailer_from'); $replyTo = FrontendModel::get('fork.settings')->get('Core', 'mailer_reply_to'); $message = Message::newInstance(FL::msg('NotificationSubject'))->setFrom(array($from['email'] => $from['name']))->setTo(array($to['email'] => $to['name']))->setReplyTo(array($replyTo['email'] => $replyTo['name']))->parseHtml('/Core/Layout/Templates/Mails/Notification.html.twig', $variables, true); FrontendModel::get('mailer')->send($message); } }
/** * 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); }
/** * Notify the admin * * @param array $comment The comment that was submitted. */ public static function notifyAdmin(array $comment) { // don't notify admin in case of spam if ($comment['status'] == 'spam') { return; } // build data for push notification if ($comment['status'] == 'moderation') { $key = 'BLOG_COMMENT_MOD'; } else { $key = 'BLOG_COMMENT'; } $author = $comment['author']; if (mb_strlen($author) > 20) { $author = mb_substr($author, 0, 19) . '…'; } $text = $comment['text']; if (mb_strlen($text) > 50) { $text = mb_substr($text, 0, 49) . '…'; } $alert = array('loc-key' => $key, 'loc-args' => array($author, $text)); // build data $data = array('api' => SITE_URL . '/api/1.0', 'id' => $comment['id']); // push it FrontendModel::pushToAppleApp($alert, null, 'default', $data); // get settings $notifyByMailOnComment = FrontendModel::get('fork.settings')->get('Blog', 'notify_by_email_on_new_comment', false); $notifyByMailOnCommentToModerate = FrontendModel::get('fork.settings')->get('Blog', 'notify_by_email_on_new_comment_to_moderate', false); // create URLs $URL = SITE_URL . FrontendNavigation::getURLForBlock('Blog', 'Detail') . '/' . $comment['post_url'] . '#comment-' . $comment['id']; $backendURL = SITE_URL . FrontendNavigation::getBackendURLForBlock('comments', 'Blog') . '#tabModeration'; // notify on all comments if ($notifyByMailOnComment) { // init var $variables = null; // comment to moderate if ($comment['status'] == 'moderation') { $variables['message'] = vsprintf(FL::msg('BlogEmailNotificationsNewCommentToModerate'), array($comment['author'], $URL, $comment['post_title'], $backendURL)); } elseif ($comment['status'] == 'published') { // comment was published $variables['message'] = vsprintf(FL::msg('BlogEmailNotificationsNewComment'), array($comment['author'], $URL, $comment['post_title'])); } $to = FrontendModel::get('fork.settings')->get('Core', 'mailer_to'); $from = FrontendModel::get('fork.settings')->get('Core', 'mailer_from'); $replyTo = FrontendModel::get('fork.settings')->get('Core', 'mailer_reply_to'); $message = \Common\Mailer\Message::newInstance(FL::msg('NotificationSubject'))->setFrom(array($from['email'] => $from['name']))->setTo(array($to['email'] => $to['name']))->setReplyTo(array($replyTo['email'] => $replyTo['name']))->parseHtml(FRONTEND_CORE_PATH . '/Layout/Templates/Mails/Notification.tpl', $variables, true); FrontendModel::get('mailer')->send($message); } elseif ($notifyByMailOnCommentToModerate && $comment['status'] == 'moderation') { // only notify on new comments to moderate and if the comment is one to moderate // set variables $variables['message'] = vsprintf(FL::msg('BlogEmailNotificationsNewCommentToModerate'), array($comment['author'], $URL, $comment['post_title'], $backendURL)); $to = FrontendModel::get('fork.settings')->get('Core', 'mailer_to'); $from = FrontendModel::get('fork.settings')->get('Core', 'mailer_from'); $replyTo = FrontendModel::get('fork.settings')->get('Core', 'mailer_reply_to'); $message = \Common\Mailer\Message::newInstance(FL::msg('NotificationSubject'))->setFrom(array($from['email'] => $from['name']))->setTo(array($to['email'] => $to['name']))->setReplyTo(array($replyTo['email'] => $replyTo['name']))->parseHtml(FRONTEND_CORE_PATH . '/Layout/Templates/Mails/Notification.tpl', $variables, true); FrontendModel::get('mailer')->send($message); } }