Example #1
0
 /**
  * Display link to publish a comment if user has edit rights
  * TODO: asimo> Use params array instead of so many param
  *
  * @param string to display before link
  * @param string to display after link
  * @param string link text
  * @param string link title
  * @param string class name
  * @param string glue between url params
  * @param boolean save context?
  * @param boolean true if create AJAX button
  * @return boolean TRUE - if the publish link is available
  */
 function publish_link($before = ' ', $after = ' ', $text = '#', $title = '#', $class = '', $glue = '&', $save_context = true, $ajax_button = false, $redirect_to = NULL)
 {
     global $current_User;
     if (!is_logged_in(false)) {
         return false;
     }
     if (!$current_User->check_perm('comment!CURSTATUS', 'edit', false, $this)) {
         // User has no permission to edit this comment
         return false;
     }
     $this->get_Item();
     $target_blog_ID = $this->Item->get_blog_ID();
     // get the current User highest publish status in this comment item blog
     list($highest_status, $publish_text) = get_highest_publish_status('comment', $target_blog_ID);
     if (compare_visibility_status($highest_status, $this->status) <= 0) {
         // Current User has no permission to change this comment status to a more public status
         return false;
     }
     $status_order = get_visibility_statuses('ordered-array');
     $status_index = get_visibility_statuses('ordered-index', array('redirected'));
     if (isset($status_index[$highest_status]) && isset($status_order[$status_index[$highest_status]]) && !empty($status_order[$status_index[$highest_status]][3])) {
         // Get color of button icon
         $status_icon_color = $status_order[$status_index[$highest_status]][3];
     } else {
         // Use green arrow as default
         $status_icon_color = 'green';
     }
     $params = array('before' => $before, 'after' => $after, 'text' => $text == '#' ? get_icon('move_up_' . $status_icon_color, 'imgtag') . ' ' . $publish_text : $text, 'title' => $title == '#' ? $publish_text : $title, 'class' => $class, 'glue' => $glue, 'save_context' => $save_context, 'ajax_button' => $ajax_button, 'redirect_to' => $redirect_to, 'status' => $highest_status, 'action' => 'publish');
     // Display the publish link
     echo $this->get_moderation_link($params);
     return true;
 }
Example #2
0
 /**
  * Add new link to owner Item
  *
  * @param integer file ID
  * @param integer link position ( 'teaser', 'teaserperm', 'teaserlink', 'aftermore', 'inline', 'fallback' )
  * @param int order of the link
  * @param boolean true to update owner last touched timestamp after link was created, false otherwise
  * @return integer|boolean Link ID on success, false otherwise
  */
 function add_link($file_ID, $position = NULL, $order = 1, $update_owner = true)
 {
     if (is_null($position)) {
         // Use default link position
         $position = $this->get_default_position($file_ID);
     }
     $edited_Link = new Link();
     $edited_Link->set('itm_ID', $this->Item->ID);
     $edited_Link->set('file_ID', $file_ID);
     $edited_Link->set('position', $position);
     $edited_Link->set('order', $order);
     if ($edited_Link->dbinsert()) {
         // New link was added to the item, invalidate blog's media BlockCache
         BlockCache::invalidate_key('media_coll_ID', $this->Item->get_blog_ID());
         $FileCache =& get_FileCache();
         $File = $FileCache->get_by_ID($file_ID, false, false);
         $file_name = empty($File) ? '' : $File->get_name();
         syslog_insert(sprintf('File %s was linked to %s with ID=%s', '<b>' . $file_name . '</b>', $this->type, $this->link_Object->ID), 'info', 'file', $file_ID);
         if ($update_owner) {
             // Update last touched date of the Item
             $this->update_last_touched_date();
         }
         // Reset the Links
         $this->Links = NULL;
         $this->load_Links();
         return $edited_Link->ID;
     }
     return false;
 }
Example #3
0
 /**
  * Generate permalink to this comment.
  *
  * Note: This actually only returns the URL, to get a real link, use Comment::get_permanent_link()
  *
  * @param string glue between url params
  * @param string Anchor for meta comment
  */
 function get_permanent_url($glue = '&amp;', $meta_anchor = '#')
 {
     $this->get_Item();
     if ($this->is_meta()) {
         // Meta comment is not published on front-office, Get url to back-office
         global $admin_url;
         if ($meta_anchor == '#') {
             // Use default anchor:
             $meta_anchor = '#' . $this->get_anchor();
         }
         return $admin_url . '?ctrl=items' . $glue . 'blog=' . $this->Item->get_blog_ID() . $glue . 'p=' . $this->Item->ID . $glue . 'comment_type=meta' . $meta_anchor;
     } else {
         // Normal comment
         return $this->Item->get_single_url('auto', '', $glue) . '#' . $this->get_anchor();
     }
 }
Example #4
0
 $edited_Item->load_from_Request(true);
 // needs Blog set
 // Set default locations from current user
 $edited_Item->set_creator_location('country');
 $edited_Item->set_creator_location('region');
 $edited_Item->set_creator_location('subregion');
 $edited_Item->set_creator_location('city');
 $edited_Item->status = param('post_status', 'string', NULL);
 // 'published' or 'draft' or ...
 // We know we can use at least one status,
 // but we need to make sure the requested/default one is ok:
 $edited_Item->status = $Blog->get_allowed_item_status($edited_Item->status);
 // Check if new category was started to create. If yes then set up parameters for next page
 check_categories_nosave($post_category, $post_extracats);
 $edited_Item->set('main_cat_ID', $post_category);
 if ($edited_Item->main_cat_ID && get_allow_cross_posting() < 2 && $edited_Item->get_blog_ID() != $blog) {
     // the main cat is not in the list of categories; this happens, if the user switches blogs during editing:
     $edited_Item->set('main_cat_ID', $Blog->get_default_cat_ID());
 }
 $post_extracats = param('post_extracats', 'array/integer', $post_extracats);
 param('item_tags', 'string', '');
 // Trackback addresses (never saved into item)
 param('trackback_url', 'string', '');
 // Page title:
 switch (param('item_typ_ID', 'integer', 1)) {
     case 1000:
         $title = T_('New page');
         break;
     case 1600:
         $title = T_('New intro');
         break;
/**
 * Read messages from server and create posts
 *
 * @param resource $mbox created by pbm_connect() (by reference)
 * @param integer the number of messages to process
 * @param boolean TRUE if script is executed by cron
 * @return boolean true on success
 */
function pbm_process_messages(&$mbox, $limit, $cron = false)
{
    global $Settings, $debug;
    global $pbm_item_files, $pbm_messages, $pbm_items, $post_cntr, $del_cntr, $is_cron_mode;
    // This may take a very long time if there are many messages; No execution time limit:
    set_max_execution_time(0);
    // Are we in test mode?
    $test_mode_on = $Settings->get('eblog_test_mode');
    $post_cntr = 0;
    $del_cntr = 0;
    for ($index = 1; $index <= $limit; $index++) {
        // Repeat for as many messages as allowed...
        pbm_msg('<hr /><h3>' . sprintf(T_('Processing message %s:'), '#' . $index) . '</h3>', $cron);
        $html_body = '';
        $strbody = '';
        $hasAttachment = false;
        $hasRelated = false;
        $pbm_item_files = array();
        // reset the value for each new Item
        // Save email to a temporary file on hard drive, otherwise BIG attachments may take a lot of RAM:
        if (!($tmpMIME = tempnam(sys_get_temp_dir(), 'b2evoMail'))) {
            pbm_msg(T_('Could not create temporary file.'), $cron);
            continue;
        }
        // Save the whole body of a specific message from the mailbox:
        imap_savebody($mbox, $tmpMIME, $index);
        // Create random temp directory for message parts:
        $tmpDirMIME = pbm_tempdir(sys_get_temp_dir(), 'b2evo_');
        // Instanciate mime_parser.php library:
        $mimeParser = new mime_parser_class();
        $mimeParser->mbox = 0;
        // Set to 0 for parsing a *single* RFC 2822 message
        $mimeParser->decode_headers = 1;
        // Set to 1 if it is	necessary to decode message headers that may have non-ASCII	characters and use other character set encodings
        $mimeParser->ignore_syntax_errors = 1;
        // ignore syntax errors in	malformed messages.
        $mimeParser->extract_addresses = 0;
        $MIMEparameters = array('File' => $tmpMIME, 'SaveBody' => $tmpDirMIME, 'SkipBody' => 1);
        // Associative array to specify parameters for the messagedata parsing and decoding operation.
        $MIMEparameters = array('File' => $tmpMIME, 'SaveBody' => $tmpDirMIME, 'SkipBody' => 1);
        // STEP 1: Parse and decode message data and retrieve its structure:
        if (!$mimeParser->Decode($MIMEparameters, $decodedMIME)) {
            // error:
            pbm_msg(sprintf(T_('MIME message decoding error: %s at position %d.'), $mimeParser->error, $mimeParser->error_position), $cron);
            rmdir_r($tmpDirMIME);
            unlink($tmpMIME);
            continue;
        } else {
            // the specified message data was parsed successfully:
            pbm_msg(T_('MIME message decoding successful'), $cron);
            // STEP 2: Analyze (the first) parsed message to describe its contents:
            if (!$mimeParser->Analyze($decodedMIME[0], $parsedMIME)) {
                // error:
                pbm_msg(sprintf(T_('MIME message analyze error: %s'), $mimeParser->error), $cron);
                rmdir_r($tmpDirMIME);
                unlink($tmpMIME);
                continue;
            }
            // Get message $subject and $post_date from headers (by reference)
            if (!pbm_process_header($parsedMIME, $subject, $post_date, $cron)) {
                // Couldn't process message headers:
                rmdir_r($tmpDirMIME);
                unlink($tmpMIME);
                continue;
            }
            // TODO: handle type == "message" recursively
            // sam2kb> For some reason imap_qprint() demages HTML text... needs more testing
            // yura> I replaced imap_qprint() with quoted_printable_decode() to avoid notices about invalid quoted-printable sequence
            // yura> imap_qprint() and quoted_printable_decode() do empty the message text, thus they were deleted.
            if ($parsedMIME['Type'] == 'html') {
                // Mail is HTML:
                if ($Settings->get('eblog_html_enabled')) {
                    // HTML posting enabled
                    if ($debug) {
                        // Display this info only in debug mode:
                        pbm_msg(sprintf(T_('HTML message part saved as %s'), $parsedMIME['DataFile']), $cron);
                    }
                    $html_body = file_get_contents($parsedMIME['DataFile']);
                }
                foreach ($parsedMIME['Alternative'] as $alternative) {
                    // First try to get HTML alternative (when possible)
                    if ($alternative['Type'] == 'html' && $Settings->get('eblog_html_enabled')) {
                        // HTML text:
                        if ($debug) {
                            // Display this info only in debug mode:
                            pbm_msg(sprintf(T_('HTML alternative message part saved as %s'), $alternative['DataFile']), $cron);
                        }
                        $strbody = file_get_contents($alternative['DataFile']);
                        break;
                        // stop after first alternative
                    } elseif ($alternative['Type'] == 'text') {
                        // Plain text:
                        if ($debug) {
                            // Display this info only in debug mode:
                            pbm_msg(sprintf(T_('Text alternative message part saved as %s'), $alternative['DataFile']), $cron);
                        }
                        $strbody = file_get_contents($alternative['DataFile']);
                        break;
                        // stop after first alternative
                    }
                }
            } elseif ($parsedMIME['Type'] == 'text') {
                // Mail is plain text:
                if ($debug) {
                    // Display this info only in debug mode:
                    pbm_msg(sprintf(T_('Plain-text message part saved as %s'), $parsedMIME['DataFile']), $cron);
                }
                $strbody = file_get_contents($parsedMIME['DataFile']);
            }
            // Check for attachments:
            if (!empty($parsedMIME['Attachments'])) {
                $hasAttachment = true;
                foreach ($parsedMIME['Attachments'] as $file) {
                    pbm_msg(sprintf(T_('Attachment: %s stored as %s'), $file['FileName'], $file['DataFile']), $cron);
                }
            }
            // Check for inline images:
            if (!empty($parsedMIME['Related'])) {
                $hasRelated = true;
                foreach ($parsedMIME['Related'] as $file) {
                    pbm_msg(sprintf(T_('Related file with content ID: %s stored as %s'), $file['ContentID'], $file['DataFile']), $cron);
                }
            }
            if (count($mimeParser->warnings) > 0) {
                pbm_msg('<h4>' . sprintf(T_('%d warnings during decode:'), count($mimeParser->warnings)) . '</h4>', $cron);
                foreach ($mimeParser->warnings as $k => $v) {
                    pbm_msg(sprintf(T_('Warning: %s at position %s'), $v, $k), $cron);
                }
            }
        }
        unlink($tmpMIME);
        if (empty($html_body)) {
            // Plain-text message
            pbm_msg(sprintf(T_('Message type: %s'), 'TEXT'), $cron);
            pbm_msg(sprintf(T_('Message body: %s'), '<pre style="font-size:10px">' . htmlspecialchars($strbody) . '</pre>'), $cron);
            // Process body. First fix different line-endings (dos, mac, unix), remove double newlines
            $content = str_replace(array("\r", "\n\n"), "\n", trim($strbody));
            // First see if there's an <auth> tag with login and password
            if (($auth = pbm_get_auth_tag($content)) === false) {
                // No <auth> tag, let's detect legacy "username:password" on the first line
                $a_body = explode("\n", $content, 2);
                // tblue> splitting only into 2 parts allows colons in the user PW
                // Note: login and password cannot include '<' !
                $auth = explode(':', strip_tags($a_body[0]), 2);
                // Drop the first line with username and password
                $content = $a_body[1];
            }
        } else {
            // HTML message
            pbm_msg(sprintf(T_('Message type: %s'), 'HTML'), $cron);
            if (($parsed_message = pbm_prepare_html_message($html_body, $cron)) === false) {
                // No 'auth' tag provided, skip to the next message
                rmdir_r($tmpDirMIME);
                continue;
            }
            list($auth, $content) = $parsed_message;
        }
        // TODO: dh> should the password really get trimmed here?!
        $user_pass = isset($auth[1]) ? trim(remove_magic_quotes($auth[1])) : NULL;
        $user_login = trim(utf8_strtolower(remove_magic_quotes($auth[0])));
        if (empty($user_login) || empty($user_pass)) {
            pbm_msg(sprintf(T_('Please add username and password in message body in format %s.'), '"&lt;auth&gt;username:password&lt;/auth&gt;"'), $cron);
            rmdir_r($tmpDirMIME);
            continue;
        }
        // Authenticate user
        pbm_msg(T_('Authenticating user') . ': &laquo;' . $user_login . '&raquo;', $cron);
        $pbmUser =& pbm_validate_user_password($user_login, $user_pass);
        if (!$pbmUser) {
            pbm_msg(sprintf(T_('Authentication failed for user &laquo;%s&raquo;'), htmlspecialchars($user_login)), $cron);
            rmdir_r($tmpDirMIME);
            continue;
        }
        $pbmUser->get_Group();
        // Load group
        if (!empty($is_cron_mode)) {
            // Assign current User if we are in cron mode. This is needed in order to check user permissions
            global $current_User;
            $current_User = duplicate($pbmUser);
        }
        // Activate User's locale
        locale_activate($pbmUser->get('locale'));
        pbm_msg('<b class="green">' . T_('Success') . '</b>', $cron);
        if ($post_categories = xmlrpc_getpostcategories($content)) {
            $main_cat_ID = array_shift($post_categories);
            $extra_cat_IDs = $post_categories;
            pbm_msg(T_('Extra categories') . ': ' . implode(', ', $extra_cat_IDs), $cron);
        } else {
            $main_cat_ID = $Settings->get('eblog_default_category');
            $extra_cat_IDs = array();
        }
        pbm_msg(T_('Main category ID') . ': ' . $main_cat_ID, $cron);
        $ChapterCache =& get_ChapterCache();
        $pbmChapter =& $ChapterCache->get_by_ID($main_cat_ID, false, false);
        if (empty($pbmChapter)) {
            pbm_msg(sprintf(T_('Requested category %s does not exist!'), $main_cat_ID), $cron);
            rmdir_r($tmpDirMIME);
            continue;
        }
        $blog_ID = $pbmChapter->blog_ID;
        pbm_msg(T_('Blog ID') . ': ' . $blog_ID, $cron);
        $BlogCache =& get_BlogCache();
        $pbmBlog =& $BlogCache->get_by_ID($blog_ID, false, false);
        if (empty($pbmBlog)) {
            pbm_msg(sprintf(T_('Requested blog %s does not exist!'), $blog_ID), $cron);
            rmdir_r($tmpDirMIME);
            continue;
        }
        // Check permission:
        pbm_msg(sprintf(T_('Checking permissions for user &laquo;%s&raquo; to post to Blog #%d'), $user_login, $blog_ID), $cron);
        if (!$pbmUser->check_perm('blog_post!published', 'edit', false, $blog_ID)) {
            pbm_msg(T_('Permission denied.'), $cron);
            rmdir_r($tmpDirMIME);
            continue;
        }
        if (($hasAttachment || $hasRelated) && !$pbmUser->check_perm('files', 'add', false, $blog_ID)) {
            pbm_msg(T_('You have no permission to add/upload files.'), $cron);
            rmdir_r($tmpDirMIME);
            continue;
        }
        pbm_msg('<b class="green">' . T_('Success') . '</b>', $cron);
        // Remove content after terminator
        $eblog_terminator = $Settings->get('eblog_body_terminator');
        if (!empty($eblog_terminator) && ($os_terminator = utf8_strpos($content, $eblog_terminator)) !== false) {
            $content = utf8_substr($content, 0, $os_terminator);
        }
        $post_title = pbm_get_post_title($content, $subject);
        // Remove 'title' and 'category' tags
        $content = xmlrpc_removepostdata($content);
        // Remove <br> tags from string start and end
        // We do it here because there might be extra <br> left after deletion of <auth>, <category> and <title> tags
        $content = preg_replace(array('~^(\\s*<br[\\s/]*>\\s*){1,}~i', '~(\\s*<br[\\s/]*>\\s*){1,}$~i'), '', $content);
        if ($hasAttachment || $hasRelated) {
            // Handle attachments
            if (isset($GLOBALS['files_Module'])) {
                if ($mediadir = $pbmBlog->get_media_dir()) {
                    if ($hasAttachment) {
                        pbm_process_attachments($content, $parsedMIME['Attachments'], $mediadir, $pbmBlog->get_media_url(), $Settings->get('eblog_add_imgtag'), 'attach', $cron);
                    }
                    if ($hasRelated) {
                        pbm_process_attachments($content, $parsedMIME['Related'], $mediadir, $pbmBlog->get_media_url(), true, 'related', $cron);
                    }
                } else {
                    pbm_msg(T_('Unable to access media directory. No attachments processed.'), $cron);
                }
            } else {
                pbm_msg(T_('Files module is disabled or missing!'), $cron);
            }
        }
        // CHECK and FORMAT content
        global $Plugins;
        $renderer_params = array('Blog' => &$pbmBlog, 'setting_name' => 'coll_apply_rendering');
        $renderers = $Plugins->validate_renderer_list($Settings->get('eblog_renderers'), $renderer_params);
        pbm_msg(sprintf(T_('Applying the following text renderers: %s'), implode(', ', $renderers)), $cron);
        // Do some optional filtering on the content
        // Typically stuff that will help the content to validate
        // Useful for code display
        // Will probably be used for validation also
        $Plugins_admin =& get_Plugins_admin();
        $params = array('object_type' => 'Item', 'object_Blog' => &$pbmBlog);
        $Plugins_admin->filter_contents($post_title, $content, $renderers, $params);
        pbm_msg(sprintf(T_('Filtered post content: %s'), '<pre style="font-size:10px">' . htmlspecialchars($content) . '</pre>'), $cron);
        $context = $Settings->get('eblog_html_tag_limit') ? 'commenting' : 'posting';
        $post_title = check_html_sanity($post_title, $context, $pbmUser);
        $content = check_html_sanity($content, $context, $pbmUser);
        global $Messages;
        if ($Messages->has_errors()) {
            // Make it easier for user to find and correct the errors
            pbm_msg("\n" . sprintf(T_('Processing message: %s'), $post_title), $cron);
            pbm_msg($Messages->get_string(T_('Cannot post, please correct these errors:'), 'error'), $cron);
            $Messages->clear();
            rmdir_r($tmpDirMIME);
            continue;
        }
        if ($test_mode_on) {
            // Test mode
            pbm_msg('<b class="green">' . T_('It looks like the post can be successfully saved in the database. However we will not do it in test mode.') . '</b>', $cron);
        } else {
            load_class('items/model/_item.class.php', 'Item');
            global $pbm_items, $DB, $localtimenow;
            $post_status = 'published';
            pbm_msg('<h4>' . sprintf(T_('Saving item "%s" in the database'), $post_title) . '</h4>', $cron);
            // INSERT NEW POST INTO DB:
            $edited_Item = new Item();
            $edited_Item->set_creator_User($pbmUser);
            $edited_Item->set($edited_Item->lasteditor_field, $pbmUser->ID);
            $edited_Item->set('title', $post_title);
            $edited_Item->set('content', $content);
            $edited_Item->set('datestart', $post_date);
            $edited_Item->set('datemodified', date('Y-m-d H:i:s', $localtimenow));
            $edited_Item->set('main_cat_ID', $main_cat_ID);
            $edited_Item->set('extra_cat_IDs', $extra_cat_IDs);
            $edited_Item->set('status', $post_status);
            $edited_Item->set('locale', $pbmUser->locale);
            $edited_Item->set('renderers', $renderers);
            // INSERT INTO DB:
            $edited_Item->dbinsert();
            pbm_msg(sprintf(T_('Item created?: %s'), isset($edited_Item->ID) ? 'yes' : 'no'), $cron);
            // Execute or schedule notifications & pings:
            $edited_Item->handle_post_processing(true);
            if (!empty($pbm_item_files)) {
                // Attach files
                $FileCache =& get_FileCache();
                $order = 1;
                foreach ($pbm_item_files as $filename) {
                    pbm_msg(sprintf(T_('Saving file "%s" in the database'), $filename), $cron);
                    $pbmFile =& $FileCache->get_by_root_and_path('collection', $pbmBlog->ID, $filename);
                    $pbmFile->meta = 'notfound';
                    // Save time and don't try to load meta from DB, it's not there anyway
                    $pbmFile->dbsave();
                    pbm_msg(sprintf(T_('File saved?: %s'), isset($pbmFile->ID) ? 'yes' : 'no'), $cron);
                    pbm_msg(sprintf(T_('Attaching file "%s" to the post'), $filename), $cron);
                    // Let's make the link!
                    $pbmLink = new Link();
                    $pbmLink->set('itm_ID', $edited_Item->ID);
                    $pbmLink->set('file_ID', $pbmFile->ID);
                    $pbmLink->set('position', 'aftermore');
                    $pbmLink->set('order', $order++);
                    $pbmLink->dbinsert();
                    pbm_msg(sprintf(T_('File attached?: %s'), isset($pbmLink->ID) ? 'yes' : 'no'), $cron);
                }
                // Invalidate blog's media BlockCache
                BlockCache::invalidate_key('media_coll_ID', $edited_Item->get_blog_ID());
            }
            // Save posted items sorted by author user for reports
            $pbm_items['user_' . $pbmUser->ID][] = $edited_Item;
            ++$post_cntr;
        }
        pbm_msg(T_('Message posting successful'), $cron);
        // Delete temporary directory
        rmdir_r($tmpDirMIME);
        if (!$test_mode_on && $Settings->get('eblog_delete_emails')) {
            pbm_msg(sprintf(T_('Marking message for deletion from inbox: %s'), $index), $cron);
            imap_delete($mbox, $index);
            ++$del_cntr;
        }
    }
    // Expunge messages marked for deletion
    imap_expunge($mbox);
    return true;
}