Exemplo n.º 1
0
 /**
  * Batch import an array of articles
  *
  * @param  array    $articles    Associative array of the articles
  * @return string
  */
 public function batchImport($articles)
 {
     # Loop the articles
     foreach ($articles as $i => $article) {
         # Validate the article's array keys
         if (!\Kanso\Utility\Arr::issets(['created', 'modified', 'status', 'type', 'title', 'excerpt', 'category', 'tags', 'content', 'thumbnail', 'comments_enabled'], $article)) {
             return "invalid_json";
         }
         if (!is_numeric($article['created'])) {
             return "invalid_json";
         }
         if (!is_numeric($article['modified'])) {
             return "invalid_json";
         }
         if ($article['type'] !== 'page' && $article['type'] !== 'post') {
             return "invalid_json";
         }
         if ($article['status'] !== 'published' && $article['status'] !== 'draft') {
             return "invalid_json";
         }
         # Sanitize values
         $articles[$i]['title'] = filter_var($articles[$i]['title'], FILTER_SANITIZE_STRING);
         $articles[$i]['excerpt'] = filter_var($articles[$i]['excerpt'], FILTER_SANITIZE_STRING);
         $articles[$i]['category'] = filter_var($articles[$i]['category'], FILTER_SANITIZE_STRING);
         $articles[$i]['thumbnail'] = filter_var($articles[$i]['thumbnail'], FILTER_SANITIZE_STRING);
         $articles[$i]['tags'] = filter_var($articles[$i]['tags'], FILTER_SANITIZE_STRING);
         $article['comments_enabled'] = (bool) $article['comments_enabled'];
         $articles[$i]['created'] = (int) $articles[$i]['created'];
         $articles[$i]['modified'] = (int) $articles[$i]['modified'];
         if (isset($articles[$i]['author_id'])) {
             $articles[$i]['author_id'] = (int) $articles[$i]['author_id'];
         }
         $post = $this->create();
         foreach ($articles[$i] as $key => $value) {
             $post->{$key} = $value;
         }
         if (!$post->save()) {
             return "invalid_json";
         }
     }
     return true;
 }
Exemplo n.º 2
0
 /**
  * Build HTML Pagination links
  *
  * @param  array       $args    Associative array of options (optional)
  */
 public function pagination_links($args = null)
 {
     # Default options
     $options = ['base' => \Kanso\Kanso::getInstance()->Environment()['HTTP_HOST'], 'format' => '<li class="(:class)"><a href="(:link)">(:num)</a></li>', 'current' => 1, 'total' => 1, 'context' => 2, 'show_all' => false, 'prev_next' => true, 'ellipsis' => '<li>. . .</li>', 'prev_text' => '« Previous', 'next_text' => 'Next »'];
     # Segment the reuest URI
     $uri = explode("/", trim(\Kanso\Kanso::getInstance()->Environment()['PATH_INFO'], '/'));
     # Declare the pagination string
     $pagination = '';
     # Replace the query and create a new one to get the post count;
     $queryStr = preg_replace('/limit =[^:]+:/', '', $this->queryStr);
     $queryStr = trim(preg_replace('/limit =[^:]+/', '', $queryStr));
     $queryStr = trim($queryStr, ":");
     # Load the query parser
     $parser = new QueryParser();
     # Count the posts
     $posts = $parser->countQuery($queryStr);
     $pages = \Kanso\Utility\Arr::paginate($posts, $this->pageIndex, \Kanso\Kanso::getInstance()->Config()['KANSO_POSTS_PER_PAGE']);
     # If no args were defined, Kanso will figure it out for us
     if (!$args || !isset($args['current']) || !isset($args['total'])) {
         # pages here are used as for an array so +1
         $options['current'] = $this->pageIndex === 0 ? 1 : $this->pageIndex + 1;
         $options['total'] = count($pages);
     }
     # If options were set, overwrite the dafaults
     if ($args) {
         $options = array_merge($options, $args);
     }
     # Special case if there is only 1 page
     if ($options['total'] == 1 || $options['total'] == 0 || $options['total'] < 1) {
         return '';
     }
     # Clean the base url
     $options['base'] = rtrim($options['base'], '/');
     # Update the base url depending on the page type
     if ($this->is_search()) {
         $options['base'] = $options['base'] . DIRECTORY_SEPARATOR . 'search-results/?q=' . $this->searchQuery;
     } else {
         if ($this->is_archive()) {
             $options['base'] = $options['base'] . DIRECTORY_SEPARATOR . 'archive';
         } else {
             if ($this->is_tag()) {
                 $options['base'] = $options['base'] . DIRECTORY_SEPARATOR . $uri[0] . DIRECTORY_SEPARATOR . $uri[1];
             } else {
                 if ($this->is_category()) {
                     $options['base'] = $options['base'] . DIRECTORY_SEPARATOR . $uri[0] . DIRECTORY_SEPARATOR . $uri[1];
                 } else {
                     if ($this->is_author()) {
                         $options['base'] = $options['base'] . DIRECTORY_SEPARATOR . $uri[0] . DIRECTORY_SEPARATOR . $uri[1];
                     }
                 }
             }
         }
     }
     # loop always at the current minus the context, minus 1
     $loopStart = $options['current'] - $options['context'];
     # if the loop starts before 2, reset it to 2
     if ($loopStart < 2) {
         $loopStart = 2;
     }
     # Loop end is the context * 2 + loop start + plus 1
     $loopEnd = $loopStart + $options['context'] * 2 + 1;
     # We should show all links if the loop ends after the total
     if ($loopEnd >= $options['total'] || $options['show_all'] === true) {
         $loopEnd = $options['total'];
     }
     # Declare variables we are going to use
     $frontEllipsis = $loopStart > 2 ? $options['ellipsis'] : '';
     $backEllipsis = $loopEnd === $options['total'] || $options['total'] - $options['context'] === $loopEnd ? '' : $options['ellipsis'];
     # Variables we will need
     $patterns = ['/\\(:class\\)/', '/\\(:link\\)/', '/\\(:num\\)/'];
     $replacements = [];
     # If show all is true we need reset
     if ($options['show_all'] === true) {
         $frontEllipsis = '';
         $backEllipsis = '';
         $loopStart = 2;
         $loopEnd = $options['total'];
     }
     # If show previous
     if ($options['prev_next'] === true) {
         $class = $options['current'] === 1 ? 'disabled' : '';
         $link = $options['current'] === 1 ? '#' : $options['base'] . DIRECTORY_SEPARATOR . 'page' . DIRECTORY_SEPARATOR . ($options['current'] - 1) . DIRECTORY_SEPARATOR;
         $link = $options['current'] === 2 ? $options['base'] : $link;
         $replacements = [$class, $link, $options['prev_text']];
         $pagination .= preg_replace($patterns, $replacements, $options['format']);
         $replacements = [];
     }
     # Show the first page
     $class = $options['current'] === 1 ? 'active' : '';
     $link = $options['current'] === 1 ? '#' : $options['base'];
     $replacements = [$class, $link, 1];
     $pagination .= preg_replace($patterns, $replacements, $options['format']);
     $replacements = [];
     # Show the front ellipsis
     $pagination .= $frontEllipsis;
     # Loop over the pages
     # Note the loop starts after the first page and before the last page
     for ($i = $loopStart; $i < $loopEnd; $i++) {
         $class = $i === $options['current'] ? 'active' : '';
         $link = $i === $options['current'] ? '#' : $options['base'] . DIRECTORY_SEPARATOR . 'page' . DIRECTORY_SEPARATOR . $i . DIRECTORY_SEPARATOR;
         $replacements = [$class, $link, $i];
         $pagination .= preg_replace($patterns, $replacements, $options['format']);
         $replacements = [];
     }
     # Show the back ellipsis
     $pagination .= $backEllipsis;
     # Show the last page
     $class = $options['current'] === $options['total'] ? 'active' : '';
     $link = $options['current'] === $options['total'] ? '#' : $options['base'] . DIRECTORY_SEPARATOR . 'page' . DIRECTORY_SEPARATOR . $options['total'] . DIRECTORY_SEPARATOR;
     $replacements = [$class, $link, $options['total']];
     $pagination .= preg_replace($patterns, $replacements, $options['format']);
     $replacements = [];
     # If show next
     if ($options['prev_next'] === true) {
         $class = $options['current'] < $options['total'] ? '' : 'disabled';
         $link = $options['current'] < $options['total'] ? $options['base'] . DIRECTORY_SEPARATOR . 'page' . DIRECTORY_SEPARATOR . ($options['current'] + 1) . DIRECTORY_SEPARATOR : '#';
         $replacements = [$class, $link, $options['next_text']];
         $pagination .= preg_replace($patterns, $replacements, $options['format']);
     }
     return $pagination;
 }
Exemplo n.º 3
0
 /**
  * Get the count of all the articles for pagination total
  *
  * @return int
  */
 private function countAllArticles()
 {
     if (!$this->isLoggedIn) {
         return false;
     }
     $perPage = 10;
     $offset = 0 * $perPage;
     $limit = $perPage;
     $articles = \Kanso\Kanso::getInstance()->Database->Builder()->SELECT('post.id')->FROM('posts')->FIND_ALL();
     return count(\Kanso\Utility\Arr::paginate($articles, 0, 10));
 }
Exemplo n.º 4
0
 public function save()
 {
     # Initialize joins if they have not been already
     $this->getTheCategory();
     $this->getTheTags();
     $this->getTheAuthor();
     $this->getTheContent();
     # Get the bookkeeper
     $bookkeeper = \Kanso\Kanso::getInstance()->Bookkeeper;
     # Update Kanso's static pages if the status has changed
     # and/or the article type has changed
     if ($this->row['status'] !== $this->tmpRow['status'] && isset($this->row['id'])) {
         $bookkeeper->changeStatus($this->row['id'], $this->tmpRow['status']);
     }
     # If no updates are required return;
     if ($this->tmpRow === $this->row && isset($this->row['id'])) {
         return;
     }
     # Save the article
     $save = $bookkeeper->saveArticle(array_merge($this->row, $this->tmpRow));
     # Merge the results
     if ($save) {
         $save['tags'] = \Kanso\Utility\Arr::implodeByKey('name', $save['tags'], ', ');
         $this->tmpRow = array_merge($this->tmpRow, $save);
         $this->row = array_merge($this->row, $save);
         return true;
     } else {
         return false;
     }
 }
Exemplo n.º 5
0
 /**
  * Send comment emails to subscribers where needed
  *
  * @param  array    $articleRow    Associative array of article data
  * @param  array    $newComment    Associative array of comment data
  * @return bool   
  */
 private static function sendCommentEmails($articleRow, $newComment)
 {
     # Is this a reply comment
     $isReply = $newComment['type'] === 'reply';
     # Get a new Query builder
     $Query = self::$Kanso->Database()->Builder();
     # Get all the comments from the article into a multi-array
     $allComments = self::buildCommentTree(self::$Kanso->Query->get_comments((int) $articleRow['id'], false));
     # Get all the emails that are subscibed to the entire article
     $allEmails = self::getAllCommentEmails($allComments);
     # Get all the admin email address
     $adminEmails = $Query->SELECT('email')->FROM('users')->WHERE('status', '=', 'confirmed')->AND_WHERE('role', '=', 'administrator')->AND_WHERE('email_notifications', '=', true)->FIND_ALL();
     # Get all the emails that are subscribed to the thread
     $threadEmails = [];
     $parentComment = [];
     if ($isReply) {
         $threadEmails = self::getThreadEmails(self::getTopCommentThread($newComment, $allComments));
         $parentComment = self::$Kanso->Query->get_comment($newComment['parent']);
     }
     # Build an array with comment variables to send email
     $website = self::$Kanso->Environment['KANSO_WEBSITE_NAME'];
     $commentVars = ['name' => $newComment['name'], 'id' => $newComment['id'], 'date' => $newComment['date'], 'articlePermalink' => self::$Kanso->Query->the_permalink($articleRow['id']), 'articleTitle' => $articleRow['title'], 'avatar' => self::$Kanso->Query->get_avatar($newComment['email'], 20, true), 'content' => self::cleanHTMLTags($newComment['html_content']), 'websiteLink' => self::$Kanso->Environment['HTTP_HOST'], 'website' => $website];
     # If this is a reply we need the parent comment
     if ($isReply) {
         # Append the parent comment to the comment vars array
         $commentVars['parent'] = ['name' => $parentComment['name'], 'id' => $parentComment['id'], 'date' => $parentComment['date'], 'avatar' => self::$Kanso->Query->get_avatar($parentComment['email'], 20, true), 'content' => self::cleanHTMLTags($parentComment['html_content'])];
     }
     $msg = $isReply ? \Kanso\Templates\Templater::getTemplate($commentVars, 'EmailReplyComment') : \Kanso\Templates\Templater::getTemplate($commentVars, 'EmailStandAloneComment');
     # Send emails to thread subscribers
     if ($isReply && !empty($threadEmails)) {
         foreach ($threadEmails as $emailAddress => $name) {
             # Don't send emails to the peson commenting
             if ($emailAddress === $newComment['email']) {
                 continue;
             }
             # Don't send emails to admins
             if (\Kanso\Utility\Arr::inMulti($emailAddress, $adminEmails)) {
                 continue;
             }
             # Send the email
             \Kanso\Utility\Mailer::sendHTMLEmail($emailAddress, $website, 'no-reply@' . $website, 'Someone just replied to a comment at you made at ' . $website . ' on ' . $articleRow['title'] . '.', $msg);
         }
     }
     # Send email to all subscribers
     if (!empty($allEmails)) {
         foreach ($allEmails as $emailAddress => $name) {
             # Don't send emails to the peson commenting
             if ($emailAddress === $newComment['email']) {
                 continue;
             }
             # Don't send email twice to people who have subscribed to their own comment
             # as well as the entire article
             if (isset($threadEmails[$emailAddress])) {
                 continue;
             }
             # Don't send emails to admins
             if (\Kanso\Utility\Arr::inMulti($emailAddress, $adminEmails)) {
                 continue;
             }
             \Kanso\Utility\Mailer::sendHTMLEmail($emailAddress, $website, 'no-reply@' . $website, 'A new comment was made at ' . $website . ' on ' . $articleRow['title'], $msg);
         }
     }
     # Send the email to all the admins on the Kanso blog
     $admins = $Query->SELECT('*')->FROM('users')->WHERE('status', '=', 'confirmed')->AND_WHERE('role', '=', 'administrator')->FIND_ALL();
     foreach ($admins as $admin) {
         # Don't send emails to the peson commenting
         if ($admin['email'] === $newComment['email']) {
             continue;
         }
         # Add the admin to the comment variables
         $commentVars['admin'] = $admin;
         # Reset the email message
         $msg = \Kanso\Templates\Templater::getTemplate($commentVars, 'EmailAdminComment');
         # Send the email
         \Kanso\Utility\Mailer::sendHTMLEmail($admin['email'], $website, 'no-reply@' . $website, 'A new comment was made at ' . $website . ' on ' . $articleRow['title'], $msg);
     }
 }
Exemplo n.º 6
0
 /**
  * Get the comments for listing in the admin panel
  *
  * @param  $queries    array     POST data from client
  * @param  $filter     string
  * @return array
  */
 public function loadAllComments($queries, $filter)
 {
     # Get the Kanso Query object
     $Query = \Kanso\Kanso::getInstance()->Query();
     # Get the SQL builder
     $SQL = \Kanso\Kanso::getInstance()->Database->Builder();
     $isSearch = $queries['search'] !== 'false';
     $page = (int) $queries['page'] - 1;
     $comments = [];
     $sort = $queries['sortBy'] === 'newest' ? 'DESC' : 'ASC';
     if ($isSearch) {
         $validKeys = ['ip' => 'ip_address', 'status' => 'status', 'user' => 'name', 'email' => 'email'];
         $searchValue = $queries['search'];
         $searchKey = false;
         if (\Kanso\Utility\Str::contains($searchValue, ':')) {
             $value = \Kanso\Utility\Str::getAfterFirstChar($searchValue, ':');
             $key = \Kanso\Utility\Str::getBeforeFirstChar($searchValue, ':');
             $key = isset($validKeys[$key]) ? $validKeys[$key] : false;
             if ($key) {
                 $searchKey = $key;
                 $searchValue = $value;
             }
         }
         if ($searchKey) {
             $comments = $SQL->SELECT('*')->FROM('comments')->WHERE($searchKey, '=', $searchValue);
         } else {
             $comments = $SQL->SELECT('*')->FROM('comments')->WHERE('content', 'LIKE', "%{$searchValue}%");
         }
         if ($filter === 'all') {
             $comments = $comments->ORDER_BY('date', $sort)->FIND_ALL();
         }
         if ($filter === 'approved') {
             $comments = $comments->WHERE('status', '=', 'approved')->ORDER_BY('date', $sort)->FIND_ALL();
         }
         if ($filter === 'spam') {
             $comments = $comments->WHERE('status', '=', 'spam')->ORDER_BY('date', $sort)->FIND_ALL();
         }
         if ($filter === 'pending') {
             $comments = $comments->WHERE('status', '=', 'pending')->ORDER_BY('date', $sort)->FIND_ALL();
         }
         if ($filter === 'deleted') {
             $comments = $comments->WHERE('status', '=', 'deleted')->ORDER_BY('date', $sort)->FIND_ALL();
         }
     } else {
         if ($filter === 'all') {
             $comments = $SQL->SELECT('*')->FROM('comments')->ORDER_BY('date', $sort)->FIND_ALL();
         }
         if ($filter === 'approved') {
             $comments = $SQL->SELECT('*')->FROM('comments')->WHERE('status', '=', 'approved')->ORDER_BY('date', $sort)->FIND_ALL();
         }
         if ($filter === 'spam') {
             $comments = $SQL->SELECT('*')->FROM('comments')->WHERE('status', '=', 'spam')->ORDER_BY('date', $sort)->FIND_ALL();
         }
         if ($filter === 'pending') {
             $comments = $SQL->SELECT('*')->FROM('comments')->WHERE('status', '=', 'pending')->ORDER_BY('date', $sort)->FIND_ALL();
         }
         if ($filter === 'deleted') {
             $comments = $SQL->SELECT('*')->FROM('comments')->WHERE('status', '=', 'deleted')->ORDER_BY('date', $sort)->FIND_ALL();
         }
     }
     foreach ($comments as $key => $comment) {
         $comments[$key]['permalink'] = $Query->the_permalink($comment['post_id']);
         $comments[$key]['title'] = $Query->the_title($comment['post_id']);
         $comments[$key]['avatar'] = $Query->get_avatar($comment['email'], 100, true);
     }
     $comments = \Kanso\Utility\Arr::paginate($comments, $page, 10);
     return $comments;
 }