case 'maintenance_mode': // Enable maintenance mode $success = switch_maintenance_mode(true, 'all', T_('System backup is in progress. Please reload this page in a few minutes.')); // Make sure we exit the maintenance mode if PHP dies register_shutdown_function('switch_maintenance_mode', false, '', true); break; case 'open': // Don't lock the site break; default: debug_die('Invalid system lock type received!'); break; } if ($success) { // We can start backup set_max_execution_time(1800); // 30 minutes $current_Backup->start_backup(); } // Unlock b2evolution switch ($lock_type) { case 'maintenance_lock': // Disable maintenance lock switch_maintenance_lock(false); break; case 'maintenance_mode': // Disable maintenance mode switch_maintenance_mode(false, 'all'); break; default: // Nothing to do because the b2evoltuion was not locked
/** * Delete a blog and dependencies from database * * Includes WAY TOO MANY requests because we try to be compatible with MySQL 3.23, bleh! * * @param boolean true if you want to echo progress */ function dbdelete($echo = false) { global $DB, $Messages, $Plugins; // Try to obtain some serious time to do some serious processing (5 minutes) set_max_execution_time(300); // Note: No need to localize the status messages... if ($echo) { echo '<p>MySQL 3.23 compatibility mode!'; } $DB->begin(); // Get list of cats that are going to be deleted (3.23) if ($echo) { echo '<br />Getting category list to delete... '; } $cat_list = implode(',', $DB->get_col("\n\t\t\t\tSELECT cat_ID\n\t\t\t\t FROM T_categories\n\t\t\t\t WHERE cat_blog_ID = {$this->ID}")); if (empty($cat_list)) { // There are no cats to delete if ($echo) { echo 'None!'; } } else { // Delete the cats & dependencies // Get list of posts that are going to be deleted (3.23) if ($echo) { echo '<br />Getting post list to delete... '; } $post_list = implode(',', $DB->get_col("\n\t\t\t\t\tSELECT postcat_post_ID\n\t\t\t\t\t FROM T_postcats\n\t\t\t\t\t WHERE postcat_cat_ID IN ({$cat_list})")); if (empty($post_list)) { // There are no posts to delete if ($echo) { echo 'None!'; } } else { // Delete the posts & dependencies // TODO: There's also a constraint FK_post_parent_ID.. // Delete postcats if ($echo) { echo '<br />Deleting post-categories... '; } $ret = $DB->query("DELETE FROM T_postcats\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tWHERE postcat_cat_ID IN ({$cat_list})"); if ($echo) { printf('(%d rows)', $ret); } $Messages->add(T_('Deleted post-categories'), 'success'); // Delete comments if ($echo) { echo '<br />Deleting comments on blog\'s posts... '; } $comments_list = implode(',', $DB->get_col("\n\t\t\t\t\t\tSELECT comment_ID\n\t\t\t\t\t\t FROM T_comments\n\t\t\t\t\t\t WHERE comment_post_ID IN ({$post_list})")); if (!empty($comments_list)) { // Delete the comments & dependencies $DB->query("DELETE FROM T_comments__votes\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE cmvt_cmt_ID IN ({$comments_list})"); $ret = $DB->query("DELETE FROM T_comments\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tWHERE comment_post_ID IN ({$post_list})"); } else { // No comments in this blog $ret = 0; } if ($echo) { printf('(%d rows)', $ret); } $Messages->add(T_('Deleted comments on blog\'s posts'), 'success'); // Delete posts if ($echo) { echo '<br />Deleting blog\'s posts... '; } $DB->query("DELETE FROM T_items__itemtag\n\t\t\t\t\t\t\t\t\t\t\tWHERE itag_itm_ID IN ({$post_list})"); $DB->query("DELETE FROM T_items__item_settings\n\t\t\t\t\t\t\t\t\t\t\tWHERE iset_item_ID IN ({$post_list})"); $DB->query("DELETE FROM T_items__prerendering\n\t\t\t\t\t\t\t\t\t\t\tWHERE itpr_itm_ID IN ({$post_list})"); $DB->query("DELETE FROM T_items__status\n\t\t\t\t\t\t\t\t\t\t\tWHERE pst_ID IN ({$post_list})"); $DB->query("DELETE FROM T_items__subscriptions\n\t\t\t\t\t\t\t\t\t\t\tWHERE isub_item_ID IN ({$post_list})"); $DB->query("DELETE FROM T_items__version\n\t\t\t\t\t\t\t\t\t\t\tWHERE iver_itm_ID IN ({$post_list})"); $DB->query("DELETE FROM T_links\n\t\t\t\t\t\t\t\t\t\t\tWHERE link_itm_ID IN ({$post_list})"); $DB->query("DELETE FROM T_slug\n\t\t\t\t\t\t\t\t\t\t\tWHERE slug_itm_ID IN ({$post_list})"); $ret = $DB->query("DELETE FROM T_items__item\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tWHERE post_ID IN ({$post_list})"); if ($echo) { printf('(%d rows)', $ret); } $Messages->add(T_('Deleted blog\'s posts'), 'success'); } // / are there posts? // Delete categories if ($echo) { echo '<br />Deleting blog\'s categories... '; } $ret = $DB->query("DELETE FROM T_categories\n\t\t\t\t\t\t\t\t\t\t\t\t\tWHERE cat_blog_ID = {$this->ID}"); if ($echo) { printf('(%d rows)', $ret); } $Messages->add(T_('Deleted blog\'s categories'), 'success'); } // / are there cats? // Delete the blog cache folder - try to delete even if cache is disabled load_class('_core/model/_pagecache.class.php', 'PageCache'); $PageCache = new PageCache($this); $PageCache->cache_delete(); // remember ID, because parent method resets it to 0 $old_ID = $this->ID; // Delete main (blog) object: parent::dbdelete(); $DB->commit(); // re-set the ID for the Plugin event $this->ID = $old_ID; $Plugins->trigger_event('AfterCollectionDelete', $params = array('Blog' => &$this)); $this->ID = 0; if ($echo) { echo '<br />Done.</p>'; } }
* Released under GNU GPL License - {@link http://b2evolution.net/about/license.html} * @copyright (c)2003-2013 by Francois Planque - {@link http://fplanque.com/} * * @package admin * @author fplanque: Francois PLANQUE. * * @version $Id: phpbbimport.ctrl.php 74 2011-10-26 13:49:38Z fplanque $ */ if (!defined('EVO_MAIN_INIT')) { die('Please, do not access this page directly.'); } load_funcs('tools/model/_phpbb.funcs.php'); param('action', 'string'); if (!empty($action)) { // Try to obtain some serious time to do some serious processing (15 minutes) set_max_execution_time(900); // Turn off the output buffering to do the correct work of the function flush() @ini_set('output_buffering', 'off'); } /** * @var step * * values: * 1) 'config' * 2) 'groups' * 3) 'users' * 4) 'forums' -> categories * 5) 'topics' -> posts * 6) 'replies' -> comments * 7) 'messages' */
/** * Read messages from server and create posts * * @param resource $mbox created by pbm_connect() (by reference) * @param integer the number of messages to process * @return boolean true on success */ function pbm_process_messages(&$mbox, $limit) { global $Settings; global $pbm_item_files, $pbm_messages, $pbm_items, $post_cntr, $del_cntr, $is_cron_mode; // 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++) { pbm_msg('<hr /><h3>Processing message #' . $index . ':</h3>'); $strbody = ''; $hasAttachment = false; $hasRelated = false; $pbm_item_files = array(); // reset the value for each new Item // Save email to hard drive, otherwise attachments may take a lot of RAM if (!($tmpMIME = tempnam(sys_get_temp_dir(), 'b2evoMail'))) { pbm_msg(T_('Could not create temporary file.'), true); continue; } imap_savebody($mbox, $tmpMIME, $index); // Create random temp directory for message parts $tmpDirMIME = pbm_tempdir(sys_get_temp_dir(), 'b2evo_'); $mimeParser = new mime_parser_class(); $mimeParser->mbox = 0; // Set to 0 for parsing a single message file $mimeParser->decode_headers = 1; $mimeParser->ignore_syntax_errors = 1; $mimeParser->extract_addresses = 0; $MIMEparameters = array('File' => $tmpMIME, 'SaveBody' => $tmpDirMIME, 'SkipBody' => 1); if (!$mimeParser->Decode($MIMEparameters, $decodedMIME)) { pbm_msg(sprintf('MIME message decoding error: %s at position %d.', $mimeParser->error, $mimeParser->error_position), true); rmdir_r($tmpDirMIME); unlink($tmpMIME); continue; } else { pbm_msg('MIME message decoding successful'); if (!$mimeParser->Analyze($decodedMIME[0], $parsedMIME)) { pbm_msg(sprintf('MIME message analyse error: %s', $mimeParser->error), true); rmdir_r($tmpDirMIME); unlink($tmpMIME); continue; } // Get message $subject and $post_date from headers (by reference) if (!pbm_process_header($parsedMIME, $subject, $post_date)) { // 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 if ($parsedMIME['Type'] == 'html') { // Mail is HTML if ($Settings->get('eblog_html_enabled')) { // HTML posting enabled pbm_msg('HTML message part saved as ' . $parsedMIME['DataFile']); $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 pbm_msg('HTML alternative message part saved as ' . $alternative['DataFile']); // sam2kb> TODO: we may need to use $html_body here instead $strbody = file_get_contents($alternative['DataFile']); break; // stop after first alternative } elseif ($alternative['Type'] == 'text') { // Plain text pbm_msg('Text alternative message part saved as ' . $alternative['DataFile']); $strbody = imap_qprint(file_get_contents($alternative['DataFile'])); break; // stop after first alternative } } } elseif ($parsedMIME['Type'] == 'text') { // Mail is plain text pbm_msg('Plain-text message part saved as ' . $parsedMIME['DataFile']); $strbody = imap_qprint(file_get_contents($parsedMIME['DataFile'])); } // Check for attachments if (!empty($parsedMIME['Attachments'])) { $hasAttachment = true; foreach ($parsedMIME['Attachments'] as $file) { pbm_msg('Attachment: ' . $file['FileName'] . ' stored as ' . $file['DataFile']); } } // Check for inline images if (!empty($parsedMIME['Related'])) { $hasRelated = true; foreach ($parsedMIME['Related'] as $file) { pbm_msg('Related file with content ID: ' . $file['ContentID'] . ' stored as ' . $file['DataFile']); } } if (count($mimeParser->warnings) > 0) { pbm_msg(sprintf('<h4>%d warnings during decode:</h4>', count($mimeParser->warnings))); foreach ($mimeParser->warnings as $k => $v) { pbm_msg('Warning: ' . $v . ' at position ' . $k); } } } unlink($tmpMIME); if (empty($html_body)) { // Plain text message pbm_msg('Message type: TEXT'); pbm_msg('Message body: <pre style="font-size:10px">' . htmlspecialchars($strbody) . '</pre>'); // 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('Message type: HTML'); if (($parsed_message = pbm_prepare_html_message($html_body)) === 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(evo_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.'), '"<auth>username:password</auth>"'), true); rmdir_r($tmpDirMIME); continue; } // Authenticate user pbm_msg('Authenticating user: «' . $user_login . '»'); $pbmUser =& pbm_validate_user_password($user_login, $user_pass); if (!$pbmUser) { pbm_msg(sprintf(T_('Authentication failed for user «%s»'), htmlspecialchars($user_login)), true); 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">Success</b>'); if ($post_categories = xmlrpc_getpostcategories($content)) { $main_cat_ID = array_shift($post_categories); $extra_cat_IDs = $post_categories; pbm_msg('Extra categories: ' . implode(', ', $extra_cat_IDs)); } else { $main_cat_ID = $Settings->get('eblog_default_category'); $extra_cat_IDs = array(); } pbm_msg('Main category ID: ' . $main_cat_ID); $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), true); rmdir_r($tmpDirMIME); continue; } $blog_ID = $pbmChapter->blog_ID; pbm_msg('Blog ID: ' . $blog_ID); $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), true); rmdir_r($tmpDirMIME); continue; } // Check permission: pbm_msg(sprintf('Checking permissions for user «%s» to post to Blog #%d', $user_login, $blog_ID)); if (!$pbmUser->check_perm('blog_post!published', 'edit', false, $blog_ID)) { pbm_msg(T_('Permission denied.'), true); 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.'), true); rmdir_r($tmpDirMIME); continue; } pbm_msg('<b class="green">Success</b>'); // Remove content after terminator $eblog_terminator = $Settings->get('eblog_body_terminator'); if (!empty($eblog_terminator) && ($os_terminator = evo_strpos($content, $eblog_terminator)) !== false) { $content = evo_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'); } if ($hasRelated) { pbm_process_attachments($content, $parsedMIME['Related'], $mediadir, $pbmBlog->get_media_url(), true, 'related'); } } else { pbm_msg(T_('Unable to access media directory. No attachments processed.'), true); } } else { pbm_msg(T_('Files module is disabled or missing!'), true); } } // 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('Applying the following text renderers: ' . implode(', ', $renderers)); // 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('Filtered post content: <pre style="font-size:10px">' . htmlspecialchars($content) . '</pre>'); $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), true); pbm_msg($Messages->get_string(T_('Cannot post, please correct these errors:'), 'error'), true); $Messages->clear(); rmdir_r($tmpDirMIME); continue; } if ($test_mode_on) { // Test mode pbm_msg('<b class="green">It looks like the post can be successfully saved in the database. However we will not do it in test mode.</b>'); } else { load_class('items/model/_item.class.php', 'Item'); global $pbm_items, $DB, $localtimenow; $post_status = 'published'; pbm_msg(sprintf('<h4>Saving item "%s" in the database</h4>', $post_title)); // 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('through_email'); pbm_msg(sprintf('Item created?: ' . (isset($edited_Item->ID) ? 'yes' : 'no'))); // 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('Saving file "%s" in the database', $filename)); $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('File saved?: ' . (isset($pbmFile->ID) ? 'yes' : 'no'))); pbm_msg(sprintf('Attaching file "%s" to the post', $filename)); // 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('File attached?: ' . (isset($pbmLink->ID) ? 'yes' : 'no'))); } } // Save posted items sorted by author user for reports $pbm_items['user_' . $pbmUser->ID][] = $edited_Item; ++$post_cntr; } pbm_msg('Message posting successful'); // Delete temporary directory rmdir_r($tmpDirMIME); if (!$test_mode_on && $Settings->get('eblog_delete_emails')) { pbm_msg('Marking message for deletion from inbox: ' . $index); imap_delete($mbox, $index); ++$del_cntr; } } // Expunge messages marked for deletion imap_expunge($mbox); return true; }
/** * Delete comments of the user * * @return boolean True on success */ function delete_comments() { global $DB, $current_User; // If user has a huge amount of the comments it will takes many time to delete all comments set_max_execution_time(900); $DB->begin(); // Get the comments of this user which current user can delete $comments_IDs = $this->get_own_comments_IDs(); if (!count($comments_IDs)) { // User has no comments return false; } $CommentCache =& get_CommentCache(); $ItemCache =& get_ItemCache(); // If current user can moderate this user then it is allowed to delete all user data even if it wouldn't be allowed otherwise. $current_user_can_moderate = $current_User->can_moderate_user($this->ID); $result = false; foreach ($comments_IDs as $comment_ID) { $deleted_Comment =& $CommentCache->get_by_ID($comment_ID, false, false); if ($deleted_Comment && ($current_user_can_moderate || $current_User->check_perm('comment!CURSTATUS', 'delete', false, $deleted_Comment))) { // Current user has a permission to delete this comment // Delete from DB $result = $deleted_Comment->dbdelete(true, false); if (!$result) { break; } } // Clear a cache to avoid a memory allocation error $CommentCache->clear(); $ItemCache->clear(); } if ($result) { $DB->commit(); } else { $DB->rollback(); } return $result; }
/** * Read messages from server and save returned emails into DB * * @param resource $mbox created by dre_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 dre_process_messages(&$mbox, $limit, $cron = false) { global $Settings, $debug; global $dre_messages, $dre_emails, $email_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); if ($Settings->get('repath_ignore_read')) { // Read status info of all messages in order to know which have already been read: $msg_statuses = imap_fetch_overview($mbox, '1:' . $limit); } $email_cntr = 0; $del_cntr = 0; for ($index = 1; $index <= $limit; $index++) { // Repeat for as many messages as allowed... dre_msg('<hr /><h3>' . sprintf(T_('Processing message %s:'), '#' . $index) . '</h3>', $cron); if ($Settings->get('repath_ignore_read')) { // Check if we can read this message or we should skip this: if (isset($msg_statuses[$index - 1]) && $msg_statuses[$index - 1]->seen == 1) { // Skip this message because it has already been read: dre_msg(T_('Ignoring this message because it has aleady been read.'), $cron); continue; } else { // Mark this message as "Seen" in order to don't read it twice: imap_setflag_full($mbox, $index, '\\Seen'); } } $html_body = ''; $strbody = ''; $hasAttachment = false; $hasRelated = false; // 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'))) { dre_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); // fp> TODO: soemwhere here we should skip messages that already have the "seen" flag. This should be optional but should be the default. // This will allow to keep the emails in the INBOX without reprocessing them but to easily try them again my marking them unread. // Create random temp directory for message parts: $tmpDirMIME = dre_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; // 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: dre_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: dre_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: dre_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 (!dre_process_header($parsedMIME, $subject, $post_date, $cron)) { // Couldn't process message headers: rmdir_r($tmpDirMIME); unlink($tmpMIME); continue; } // TODO: handle type == "message" recursively // fp> where is type == "message" ??? // yura> I don't find the type == 'message' in dump of $decodedMIME and $parsedMIME // 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. dre_msg(T_('Email Type') . ': ' . $parsedMIME['Type'], $cron); if ($parsedMIME['Type'] == 'html') { // Mail is HTML: if ($debug) { // Display this info only in debug mode: dre_msg(sprintf(T_('HTML message part saved as %s'), $parsedMIME['DataFile']), $cron); } $html_body = file_get_contents($parsedMIME['DataFile']); if (empty($html_body)) { // Try to get a body text from alternative parts if main html body is empty: foreach ($parsedMIME['Alternative'] as $alternative) { // First try to get HTML alternative (when possible) if ($alternative['Type'] == 'html') { // HTML text if ($debug) { // Display this info only in debug mode: dre_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: dre_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: dre_msg(sprintf(T_('Plain-text message part saved as %s'), $parsedMIME['DataFile']), $cron); } $strbody = file_get_contents($parsedMIME['DataFile']); } elseif ($parsedMIME['Type'] == 'delivery-status') { // Mail is delivery-status: $strbody = $parsedMIME['Response']; } if (count($mimeParser->warnings) > 0) { // Record potential warnings: dre_msg('<h4>' . sprintf(T_('%d warnings during decode:'), count($mimeParser->warnings)) . '</h4>', $cron); foreach ($mimeParser->warnings as $k => $v) { dre_msg(sprintf(T_('Warning: %s at position %s'), $v, $k), $cron); } } } unlink($tmpMIME); if (empty($html_body)) { // Plain-text message dre_msg(sprintf(T_('Message type: %s'), 'TEXT'), $cron); // Process body. First fix different line-endings (dos, mac, unix), remove double newlines $content = str_replace(array("\r", "\n\n"), "\n", trim($strbody)); dre_msg(sprintf(T_('Message body: %s'), '<pre style="font-size:10px">' . htmlspecialchars($strbody) . '</pre>'), $cron); } else { // HTML message dre_msg(sprintf(T_('Message type: %s'), 'HTML'), $cron); dre_msg(sprintf(T_('Message body (original): %s'), '<pre style="font-size:10px">' . htmlspecialchars($html_body) . '</pre>', $cron)); // Prepare html message body text: $content = dre_prepare_html_message($html_body); dre_msg(sprintf(T_('Message body (processed): %s'), '<pre style="font-size:10px">' . htmlspecialchars($content) . '</pre>', $cron)); } dre_msg('<b class="green">' . T_('MIME Decoding Successful') . '</b>', $cron); $message_text = $content; // Remove content after terminators $content = dre_limit_by_terminators($content); global $Messages; if ($Messages->has_errors()) { // Make it easier for user to find and correct the errors dre_msg("\n" . sprintf(T_('Processing message: %s'), $post_title), $cron); dre_msg($Messages->get_string(T_('Cannot post, please correct these errors:'), 'error'), $cron); $Messages->clear(); rmdir_r($tmpDirMIME); continue; } global $dre_emails, $DB, $localtimenow; dre_msg('<h4>' . T_('Saving the returned email in the database') . '</h4>', $cron); // Get Headers from Decoded MIME Data: $email_headers = dre_get_headers($decodedMIME); // Get data of the returned email: $email_data = dre_get_email_data($content, $message_text, $email_headers); dre_msg(T_('Email Address') . ': ' . $email_data['address'], $cron); dre_msg(T_('Error Type') . ': ' . dre_decode_error_type($email_data['errtype']), $cron); dre_msg(T_('Error Message') . ': ' . $email_data['errormsg'], $cron); // Insert a returned email's data into DB if (dre_insert_returned_email($email_data)) { ++$email_cntr; } // Delete temporary directory: rmdir_r($tmpDirMIME); // Mark message to be deleted: if ($Settings->get('repath_delete_emails')) { dre_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; }
$tab = ''; $Messages->add('Invalid sub-menu!'); // Should need no translation, prevented by GUI } } // Highlight the requested tab (if valid): $AdminUI->set_path('options', 'misc', !empty($tab) ? $tab : $tab3); if (empty($tab)) { // "Main tab" actions: if (param('action', 'string', '')) { // Check that this action request is not a CSRF hacked request: $Session->assert_received_crumb('tools'); // fp> TODO: have an option to only PRUNE files older than for example 30 days $current_User->check_perm('options', 'edit', true); } set_max_execution_time(0); $Plugins->trigger_event('AdminToolAction'); switch ($action) { case 'del_itemprecache': // Clear pre-rendered item cache (DB) dbm_delete_itemprecache(); break; case 'del_commentprecache': // Clear pre-rendered comment cache (DB) dbm_delete_commentprecache(); break; case 'del_messageprecache': // Clear pre-rendered message cache (DB) dbm_delete_messageprecache(); break; case 'del_pagecache':
$svn_revision = param('svn_revision', 'integer'); $UserSettings->set('svn_upgrade_url', $svn_url); $UserSettings->set('svn_upgrade_folder', $svn_folder); $UserSettings->set('svn_upgrade_user', $svn_user); $UserSettings->set('svn_upgrade_revision', $svn_revision); $UserSettings->dbupdate(); $success = param_check_not_empty('svn_url', T_('Please enter the URL of repository')); $success = $success && param_check_regexp('svn_folder', '#/blogs/$#', T_('A correct SVN folder path must ends with "/blogs/')); if (!$success) { $action = 'start'; break; } $success = prepare_maintenance_dir($upgrade_path, true); if ($success) { // Set maximum execution time set_max_execution_time(2400); // 60 minutes load_class('_ext/phpsvnclient/phpsvnclient.php', 'phpsvnclient'); $phpsvnclient = new phpsvnclient($svn_url, $svn_user, $svn_password); // Get an error if it was during connecting to svn server $svn_error = $phpsvnclient->getError(); if (!empty($svn_error) || $phpsvnclient->getVersion() < 1) { // Some errors or Incorrect version echo '<p class="red">' . T_('Unable to get a repository version, probably URL of repository is incorrect.') . '</p>'; evo_flush(); $action = 'start'; break; // Stop an upgrade from SVN } if ($svn_revision > 0) { // Set revision from request
require_once dirname(__FILE__) . '/_functions_evoupgrade.php'; // Progress bar start_install_progress_bar(T_('Uprade in progress'), get_upgrade_steps_count()); echo '<h2>' . T_('Upgrading b2evolution...') . '</h2>'; echo '<h2>' . T_('Checking files...') . '</h2>'; evo_flush(); // Check for .htaccess: if (!install_htaccess(true)) { // Exit installation here because the .htaccess file has the some errors break; } // Update the progress bar status update_install_progress_bar(); // Try to obtain some serious time to do some serious processing (5 minutes) // NOte: this must NOT be in upgrade_b2evo_tables(), otherwise it will mess with the longer setting used by the auto upgrade feature. if (set_max_execution_time(300) === false) { // max_execution_time ini setting could not be changed for this script, display a warning $manual_url = 'href="' . get_manual_url('blank-or-partial-page') . '" target = "_blank"'; echo '<div class="text-warning"><evo:warning>' . sprintf(T_('WARNING: the max_execution_time is set to %s seconds in php.ini and cannot be increased automatically. This may lead to a PHP <a %s>timeout causing the upgrade to fail</a>. If so please post a screenshot to the <a %s>forums</a>.'), ini_get('max_execution_time'), $manual_url, 'href="http://forums.b2evolution.net/"') . '</evo:warning></div>'; } echo '<h2>' . T_('Upgrading data in existing b2evolution database...') . '</h2>'; evo_flush(); $is_automated_upgrade = $action !== 'evoupgrade'; $upgrade_result = upgrade_b2evo_tables($action); if ($upgrade_result === 'need-fix') { // We are waiting for the user to click on "try to repair/upgrade now"... // We already displayed the orange upgrade button. Offer an alternative: // A link back to install menu display_install_back_link(); } elseif ($upgrade_result === true) { if ($is_automated_upgrade) {
/** * Recreate posts autogenerated excerpts * Only those posts excerpt will be recreated which are visible in the front office * * Note: This process can be very very slow if there are many items in the database * * @param string the url to call if the process needs to be paused becuase of the max execution time * @param boolean set true to start from the beginning, false otherwise * @param boolean set to true to display recreated/all information or leave it on false to display only dots */ function recreate_autogenerated_excerpts($continue_url, $remove_all = true, $detailed_progress_log = false) { global $DB, $localtimenow; $start_time = time(); $max_exec_time = ini_get('max_execution_time'); $load_limit = 50; $progress_log_id = 'progress_log'; // The timestamp when the process was started $process_start_ts = param('start_ts', 'string', $localtimenow); // Update only those posts which may be visible in the front office $where_condition = '( post_excerpt_autogenerated = 1 OR post_excerpt_autogenerated IS NULL ) AND post_status IN ( \'' . implode('\',\' ', get_inskin_statuses(NULL, 'post')) . '\' )'; // Update only those posts which were already created when the recreate process was started $where_condition .= ' AND post_datecreated < ' . $DB->quote(date2mysql($process_start_ts)); if ($remove_all) { // We are in the beginning of the process and first we set all autogenerated excerpts values to NULL if ($detailed_progress_log) { // Display detailed progess information echo '<span id="' . $progress_log_id . '">' . T_('Clearing autogenerated excerpt values') . '</span>'; evo_flush(); } // Set all autogenerated excerpt values to NULL $query = 'UPDATE T_items__item SET post_excerpt = NULL WHERE ' . $where_condition; $DB->query($query, 'Remove all autogenerated excerpts'); // Count all autogenerated excerpt which value is NULL ( Note: Maybe some of them was already NULL before we have started this process ) $all_excerpt = $DB->get_var('SELECT count(*) FROM T_items__item WHERE post_excerpt IS NULL AND ' . $where_condition); $recreated_excerpts = 0; } else { // Init params with a previously started process status echo '<span id="progress_log"></span>'; $all_excerpt = param('all_excerpt', 'integer', 0); $recreated_excerpts = param('recreated_excerpts', 'integer', 0); } // Display the current state of the process or a '.' character to indicate the ongoing process if ($detailed_progress_log) { echo_progress_log_update($progress_log_id, $recreated_excerpts, $all_excerpt); } else { echo ' .'; } evo_flush(); $load_SQL = new SQL(); $load_SQL->SELECT('*'); $load_SQL->FROM('T_items__item'); $load_SQL->WHERE($where_condition . ' AND post_excerpt IS NULL'); $load_SQL->LIMIT($load_limit); $ItemCache =& get_ItemCache(); while (count($ItemCache->load_by_sql($load_SQL)) > 0) { // New portion of items was loaded $processed_items = 0; while (($iterator_Item =& $ItemCache->get_next()) != NULL) { // Create new autogenerated excerpt and save it in the database $excerpt = $iterator_Item->get_autogenerated_excerpt(); // Update excerpt without Item->dbupdate() call to make it faster $DB->query('UPDATE T_items__item SET post_excerpt = ' . $DB->quote($excerpt) . ' WHERE post_ID = ' . $DB->quote($iterator_Item->ID)); $processed_items++; if ($detailed_progress_log && $processed_items % 3 == 0) { // Update progress info after every 3 recreated excerpt when detailed progress log was requested echo_progress_log_update($progress_log_id, $recreated_excerpts + $processed_items, $all_excerpt); evo_flush(); } } // Increase the number recreated excerpts $recreated_excerpts += $processed_items; // Clear already process items from the cache $ItemCache->clear(); // Display progress log if ($detailed_progress_log) { echo_progress_log_update($progress_log_id, $recreated_excerpts, $all_excerpt); } else { echo ' .'; } evo_flush(); if ($max_exec_time != 0 && $recreated_excerpts < $all_excerpt) { // a max execution time limit is set and there are more excerpts to create $elapsed_time = time() - $start_time; if ($elapsed_time > $max_exec_time - 10) { // Increase the time limit in case if less than 10 seconds remained $max_exec_time = $max_exec_time + 100; if (!set_max_execution_time($max_exec_time)) { $continue_url = url_add_param($continue_url, 'all_excerpt=' . $all_excerpt . '&recreated_excerpts=' . $recreated_excerpts . '&start_ts=' . $process_start_ts, '&'); echo '<br />' . 'We are reaching the time limit for this script. Please click <a href="' . $continue_url . '">continue</a>...'; evo_flush(); exit(0); } } } } // Check if the recreated exceprts number match with the total number of autogenerated excerpts if ($detailed_progress_log && $recreated_excerpts < $all_excerpt) { // This means that we are in the end of the process but some post excerpt was updated outside of this process // Here we increase the recreated excerpts value because all excerpts were recreated, however some of them not during this process echo_progress_log_update($progress_log_id, $all_excerpt, $all_excerpt); if ($all_excerpt == $recreated_excerpts + 1) { echo '<br />' . T_('Note: One excerpt was re-created in another simultaneous process!'); } else { echo '<br />' . sprintf(T_('Note: %d excerpts were re-created in another simultaneous process!'), $all_excerpt - $recreated_excerpts); } } }
/** * Delete a blog and dependencies from database * * @param boolean true if you want to echo progress */ function dbdelete($echo = false) { global $DB, $Messages, $Plugins, $Settings; // Try to obtain some serious time to do some serious processing (5 minutes) set_max_execution_time(300); if ($echo) { echo 'Delete collection with all of it\'s content... '; } // remember ID, because parent method resets it to 0 $old_ID = $this->ID; // Delete main (blog) object: if (!parent::dbdelete()) { $Messages->add('Blog has not been deleted.', 'error'); return false; } // Delete the blog cache folder - try to delete even if cache is disabled load_class('_core/model/_pagecache.class.php', 'PageCache'); $PageCache = new PageCache($this); $PageCache->cache_delete(); // Delete blog's media folder recursively: $FileRootCache =& get_FileRootCache(); if ($root_directory = $FileRootCache->get_root_dir('collection', $old_ID)) { // Delete the folder only when it is detected rmdir_r($root_directory); $Messages->add(T_('Deleted blog\'s files'), 'success'); } // re-set the ID for the Plugin event $this->ID = $old_ID; $Plugins->trigger_event('AfterCollectionDelete', $params = array('Blog' => &$this)); $this->ID = 0; if (isset($Settings)) { // Reset settings related to the deleted blog if ($Settings->get('default_blog_ID') == $old_ID) { // Reset default blog ID $Settings->set('default_blog_ID', 0); } if ($Settings->get('info_blog_ID') == $old_ID) { // Reset info blog ID $Settings->set('info_blog_ID', 0); } if ($Settings->get('login_blog_ID') == $old_ID) { // Reset login blog ID $Settings->set('login_blog_ID', 0); } if ($Settings->get('msg_blog_ID') == $old_ID) { // Reset messaging blog ID $Settings->set('msg_blog_ID', 0); } $Settings->dbupdate(); } if ($echo) { echo '<br />Done.</p>'; } return true; }
/** * Read messages from server and save returned emails into DB * * @param resource $mbox created by dre_connect() (by reference) * @param integer the number of messages to process * @return boolean true on success */ function dre_process_messages(&$mbox, $limit) { //return; // Exit, in development... global $Settings; global $dre_messages, $dre_emails, $email_cntr, $del_cntr, $is_cron_mode; // No execution time limit set_max_execution_time(0); $email_cntr = 0; $del_cntr = 0; for ($index = 1; $index <= $limit; $index++) { dre_msg('<hr /><h3>Processing message #' . $index . ':</h3>'); $strbody = ''; $hasAttachment = false; $hasRelated = false; // Save email to hard drive, otherwise attachments may take a lot of RAM if (!($tmpMIME = tempnam(sys_get_temp_dir(), 'b2evoMail'))) { dre_msg(T_('Could not create temporary file.'), true); continue; } imap_savebody($mbox, $tmpMIME, $index); // Create random temp directory for message parts $tmpDirMIME = dre_tempdir(sys_get_temp_dir(), 'b2evo_'); $mimeParser = new mime_parser_class(); $mimeParser->mbox = 0; // Set to 0 for parsing a single message file $mimeParser->decode_headers = 1; $mimeParser->ignore_syntax_errors = 1; $mimeParser->extract_addresses = 0; $MIMEparameters = array('File' => $tmpMIME, 'SaveBody' => $tmpDirMIME, 'SkipBody' => 1); if (!$mimeParser->Decode($MIMEparameters, $decodedMIME)) { dre_msg(sprintf('MIME message decoding error: %s at position %d.', $mimeParser->error, $mimeParser->error_position), true); rmdir_r($tmpDirMIME); unlink($tmpMIME); continue; } else { dre_msg('MIME message decoding successful'); if (!$mimeParser->Analyze($decodedMIME[0], $parsedMIME)) { dre_msg(sprintf('MIME message analyse error: %s', $mimeParser->error), true); rmdir_r($tmpDirMIME); unlink($tmpMIME); continue; } // Get message $subject and $post_date from headers (by reference) if (!dre_process_header($parsedMIME, $subject, $post_date)) { // 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 if ($parsedMIME['Type'] == 'html') { // Mail is HTML dre_msg('HTML message part saved as ' . $parsedMIME['DataFile']); $html_body = file_get_contents($parsedMIME['DataFile']); foreach ($parsedMIME['Alternative'] as $alternative) { // First try to get HTML alternative (when possible) if ($alternative['Type'] == 'html') { // HTML text dre_msg('HTML alternative message part saved as ' . $alternative['DataFile']); // sam2kb> TODO: we may need to use $html_body here instead $strbody = file_get_contents($alternative['DataFile']); break; // stop after first alternative } elseif ($alternative['Type'] == 'text') { // Plain text dre_msg('Text alternative message part saved as ' . $alternative['DataFile']); $strbody = imap_qprint(file_get_contents($alternative['DataFile'])); break; // stop after first alternative } } } elseif ($parsedMIME['Type'] == 'text') { // Mail is plain text dre_msg('Plain-text message part saved as ' . $parsedMIME['DataFile']); $strbody = imap_qprint(file_get_contents($parsedMIME['DataFile'])); } elseif ($parsedMIME['Type'] == 'delivery-status') { // Mail is delivery-status $strbody = ''; foreach ($decodedMIME[0]['Parts'] as $part) { $strbody .= imap_qprint(file_get_contents($part['BodyFile'])); } } if (count($mimeParser->warnings) > 0) { dre_msg(sprintf('<h4>%d warnings during decode:</h4>', count($mimeParser->warnings))); foreach ($mimeParser->warnings as $k => $v) { dre_msg('Warning: ' . $v . ' at position ' . $k); } } } unlink($tmpMIME); if (empty($html_body)) { // Plain text message dre_msg('Message type: TEXT'); dre_msg('Message body: <pre style="font-size:10px">' . htmlspecialchars($strbody) . '</pre>'); // Process body. First fix different line-endings (dos, mac, unix), remove double newlines $content = str_replace(array("\r", "\n\n"), "\n", trim($strbody)); } else { // HTML message dre_msg('Message type: HTML'); if (($parsed_message = dre_prepare_html_message($html_body)) === false) { // No 'auth' tag provided, skip to the next message rmdir_r($tmpDirMIME); continue; } list($auth, $content) = $parsed_message; } dre_msg('<b class="green">Success</b>'); $message_text = $content; // Remove content after terminators $content = dre_limit_by_terminators($content); global $Messages; if ($Messages->has_errors()) { // Make it easier for user to find and correct the errors dre_msg("\n" . sprintf(T_('Processing message: %s'), $post_title), true); dre_msg($Messages->get_string(T_('Cannot post, please correct these errors:'), 'error'), true); $Messages->clear(); rmdir_r($tmpDirMIME); continue; } global $dre_emails, $DB, $localtimenow; dre_msg(sprintf('<h4>Saving the returned email in the database</h4>')); // Insert a returned email's data into DB if ($returned_email = dre_insert_returned_email($content, $message_text, dre_get_headers($decodedMIME))) { dre_msg('Error Type: ' . dre_decode_error_type($returned_email['errtype'])); dre_msg('Error Message: ' . $returned_email['errormsg']); ++$email_cntr; } // Delete temporary directory rmdir_r($tmpDirMIME); if ($Settings->get('repath_delete_emails')) { dre_msg('Marking message for deletion from inbox: ' . $index); imap_delete($mbox, $index); ++$del_cntr; } } // Expunge messages market for deletion imap_expunge($mbox); return true; }