/** * mt.setPostCategories : set cats for a post * * @param xmlrpcmsg XML-RPC Message * 0 postid (string): Unique identifier of the post to edit * 1 username (string): Login for a Blogger user who is member of the blog. * 2 password (string): Password for said username. */ function mt_setPostCategories($m) { global $xmlrpcerruser, $Settings; global $DB, $Messages; // CHECK LOGIN: /** * @var User */ if (!($current_User =& xmlrpcs_login($m, 1, 2))) { // Login failed, return (last) error: return xmlrpcs_resperror(); } // GET POST: /** * @var Item */ if (!($edited_Item =& xmlrpcs_get_Item($m, 0))) { // Failed, return (last) error: return xmlrpcs_resperror(); } $xcontent = $m->getParam(3); // This is now an array of structs $contentstruct = xmlrpc_decode_recurse($xcontent); logIO("Decoded xcontent"); $categories = array(); $category = NULL; foreach ($contentstruct as $catstruct) { logIO('Category ID: ' . $catstruct['categoryId']); if (!empty($catstruct['isPrimary'])) { logIO("got primary category and there should only be one..." . $tempcat); $category = $catstruct['categoryId']; } $categories[] = $catstruct['categoryId']; } if (empty($categories)) { return new xmlrpcresp(0, $xmlrpcerruser + 4, 'No categories specified.'); } // CHECK PERMISSION: (we need perm on all categories, especially if they are in different blogs) if (!$current_User->check_perm('cats_post!' . $edited_Item->status, 'edit', false, $categories)) { // Permission denied return xmlrpcs_resperror(3); // User error 3 } logIO('Permission granted.'); if (empty($category)) { // Use first one as default: $category = $categories[0]; } logIO('Main Cat: ' . $category . ' - Other: ' . implode(',', $categories)); // UPDATE POST CATEGORIES IN DB: $edited_Item->set('main_cat_ID', $category); $edited_Item->set('extra_cat_IDs', $categories); if ($edited_Item->dbupdate() === false) { logIO('Update failed.'); return new xmlrpcresp(0, $xmlrpcerruser + 2, 'Update failed.'); } logIO('OK.'); return new xmlrpcresp(new xmlrpcval(1)); }
/** * mt.setPostCategories : set cats for a post * * @param xmlrpcmsg XML-RPC Message * 0 postid (string): Unique identifier of the post to edit * 1 username (string): Login for a Blogger user who is member of the blog. * 2 password (string): Password for said username. */ function mt_setPostCategories($m) { // CHECK LOGIN: /** * @var User */ if (!($current_User =& xmlrpcs_login($m, 1, 2))) { // Login failed, return (last) error: return xmlrpcs_resperror(); } // GET POST: /** * @var Item */ if (!($edited_Item =& xmlrpcs_get_Item($m, 0))) { // Failed, return (last) error: return xmlrpcs_resperror(); } if (!$current_User->check_perm('item_post!CURSTATUS', 'edit', false, $edited_Item)) { // Permission denied return xmlrpcs_resperror(3); } $xcontent = $m->getParam(3); // This is now an array of structs $contentstruct = xmlrpc_decode_recurse($xcontent); logIO('Decoded xcontent'); $categories = array(); $category = NULL; foreach ($contentstruct as $catstruct) { logIO('Category ID: ' . $catstruct['categoryId']); if (!empty($catstruct['isPrimary'])) { $category = $catstruct['categoryId']; logIO('got primary category and there should only be one... ' . $category); } $categories[] = $catstruct['categoryId']; } if (empty($categories)) { return xmlrpcs_resperror(4, 'No categories specified.'); } else { if (empty($category)) { // Use first one as default: $category = $categories[0]; } } // Check if category exists and can be used: $Blog =& $edited_Item->get_Blog(); if (!xmlrpcs_check_cats($category, $Blog, $categories)) { // Error: return xmlrpcs_resperror(); } // CHECK PERMISSION: (we need perm on all categories, especially if they are in different blogs) if (!$current_User->check_perm('cats_post!' . $edited_Item->status, 'edit', false, $categories)) { // Permission denied return xmlrpcs_resperror(3); // User error 3 } logIO('Permission granted.'); logIO('Main Cat: ' . $category . ' - Other: ' . implode(',', $categories)); // UPDATE POST CATEGORIES IN DB: $edited_Item->set('main_cat_ID', $category); $edited_Item->set('extra_cat_IDs', $categories); if ($edited_Item->dbupdate() === false) { logIO('Update failed.'); return xmlrpcs_resperror(99, 'Update failed.'); } logIO('OK.'); return new xmlrpcresp(new xmlrpcval(1, 'boolean')); }
/** * Log the XML-RPC call Result into LOG object * * @param object XMLRPC response object * @param Log object to add messages to * @return boolean true = success, false = error */ function xmlrpc_logresult($result, &$message_Log, $log_payload = true) { if (!$result) { // We got no response: $message_Log->add(T_('No response!'), 'error'); return false; } if ($result->faultCode()) { // We got a remote error: $message_Log->add(T_('Remote error') . ': ' . $result->faultString() . ' (' . $result->faultCode() . ')', 'error'); return false; } if ($log_payload) { // We got a response: $value = xmlrpc_decode_recurse($result->value()); if (is_array($value)) { $out = ''; foreach ($value as $l_value) { $out .= ' [' . var_export($l_value, true) . '] '; } } else { $out = $value; } $message_Log->add(T_('Response') . ': ' . $out, 'success'); } return true; }
/** * metaWeblog.newMediaObject image upload * wp.uploadFile * * Supplied image is encoded into the struct as bits * * @see http://www.xmlrpc.com/metaWeblogApi#metaweblognewmediaobject * @see http://codex.wordpress.org/XML-RPC_wp#wp.uploadFile * * @param xmlrpcmsg XML-RPC Message * 0 blogid (string): Unique identifier of the blog the post will be added to. * Currently ignored in b2evo, in favor of the category. * 1 username (string): Login for a Blogger user who has permission to edit the given * post (either the user who originally created it or an admin of the blog). * 2 password (string): Password for said username. * 3 struct (struct) * - name : filename * - type : mimetype * - bits : base64 encoded file * @return xmlrpcresp XML-RPC Response */ function _wp_mw_newmediaobject($m) { global $Settings, $Plugins, $force_upload_forbiddenext; // CHECK LOGIN: /** * @var User */ if (!($current_User =& xmlrpcs_login($m, 1, 2))) { // Login failed, return (last) error: return xmlrpcs_resperror(); } // GET BLOG: /** * @var Blog */ if (!($Blog =& xmlrpcs_get_Blog($m, 0))) { // Login failed, return (last) error: return xmlrpcs_resperror(); } // CHECK PERMISSION: if (!$current_User->check_perm('files', 'add', false, $Blog->ID)) { // Permission denied return xmlrpcs_resperror(3); // User error 3 } logIO('Permission granted.'); if (!$Settings->get('upload_enabled')) { return xmlrpcs_resperror(2, 'Object upload not allowed'); } $xcontent = $m->getParam(3); // Get the main data - and decode it properly for the image - sorry, binary object logIO('Decoding content...'); $contentstruct = xmlrpc_decode_recurse($xcontent); $data = $contentstruct['bits']; $file_mimetype = isset($contentstruct['type']) ? $contentstruct['type'] : '(none)'; logIO('Received MIME type: ' . $file_mimetype); $overwrite = false; if (isset($contentstruct['overwrite'])) { $overwrite = (bool) $contentstruct['overwrite']; } logIO('Overwrite if exists: ' . ($overwrite ? 'yes' : 'no')); load_funcs('files/model/_file.funcs.php'); $filesize = evo_bytes($data); if (($maxfilesize = $Settings->get('upload_maxkb') * 1024) && $filesize > $maxfilesize) { return xmlrpcs_resperror(4, sprintf(T_('The file is too large: %s but the maximum allowed is %s.'), bytesreadable($filesize, false), bytesreadable($maxfilesize, false))); } logIO('File size is OK: ' . bytesreadable($filesize, false)); $FileRootCache =& get_FileRootCache(); $fm_FileRoot =& $FileRootCache->get_by_type_and_ID('collection', $Blog->ID, true); if (!$fm_FileRoot) { // fileRoot not found: return xmlrpcs_resperror(14, 'File root not found'); } $rf_filepath = $contentstruct['name']; logIO('Received filepath: ' . $rf_filepath); // Split into path + name: $filepath_parts = explode('/', $rf_filepath); $filename = array_pop($filepath_parts); logIO('Original file name: ' . $filename); // Validate and sanitize filename if ($error_filename = process_filename($filename, true)) { return xmlrpcs_resperror(5, $error_filename); } logIO('Sanitized file name: ' . $filename); // Check valid path parts: $rds_subpath = ''; foreach ($filepath_parts as $filepath_part) { if (empty($filepath_part) || $filepath_part == '.') { // self ref not useful continue; } if ($error = validate_dirname($filepath_part)) { // invalid relative path: logIO($error); return xmlrpcs_resperror(6, $error); } $rds_subpath .= $filepath_part . '/'; } logIO('Subpath: ' . $rds_subpath); // Create temporary file and insert contents into it. $tmpfile_name = tempnam(sys_get_temp_dir(), 'fmupload'); if ($tmpfile_name) { if (save_to_file($data, $tmpfile_name, 'wb')) { $image_info = @getimagesize($tmpfile_name); } else { return xmlrpcs_resperror(13, 'Error while writing to temp file.'); } } if (!empty($image_info)) { // This is an image file, let's check mimetype and correct extension if ($image_info['mime'] != $file_mimetype) { // Invalid file type $FiletypeCache =& get_FiletypeCache(); // Get correct file type based on mime type $correct_Filetype = $FiletypeCache->get_by_mimetype($image_info['mime'], false, false); $file_mimetype = $image_info['mime']; // Check if file type is known by us, and if it is allowed for upload. // If we don't know this file type or if it isn't allowed we don't change the extension! The current extension is allowed for sure. if ($correct_Filetype && $correct_Filetype->is_allowed()) { // A FileType with the given mime type exists in database and it is an allowed file type for current User // The "correct" extension is a plausible one, proceed... $correct_extension = array_shift($correct_Filetype->get_extensions()); $path_info = pathinfo($filename); $current_extension = $path_info['extension']; // change file extension to the correct extension, but only if the correct extension is not restricted, this is an extra security check! if (strtolower($current_extension) != strtolower($correct_extension) && !in_array($correct_extension, $force_upload_forbiddenext)) { // change the file extension to the correct extension $old_filename = $filename; $filename = $path_info['filename'] . '.' . $correct_extension; } } } } // Get File object for requested target location: $FileCache =& get_FileCache(); $newFile =& $FileCache->get_by_root_and_path($fm_FileRoot->type, $fm_FileRoot->in_type_ID, trailing_slash($rds_subpath) . $filename, true); if ($newFile->exists()) { if ($overwrite && $newFile->unlink()) { // OK, file deleted // Delete thumb caches from old location: logIO('Old file deleted'); $newFile->rm_cache(); } else { return xmlrpcs_resperror(8, sprintf(T_('The file «%s» already exists.'), $filename)); } } // Trigger plugin event if ($Plugins->trigger_event_first_false('AfterFileUpload', array('File' => &$newFile, 'name' => &$filename, 'type' => &$file_mimetype, 'tmp_name' => &$tmpfile_name, 'size' => &$filesize))) { // Plugin returned 'false'. // Abort upload for this file: @unlink($tmpfile_name); return xmlrpcs_resperror(16, 'File upload aborted by a plugin.'); } if (!mkdir_r($newFile->get_dir())) { // Dir didn't already exist and could not be created return xmlrpcs_resperror(9, 'Error creating sub directories: ' . $newFile->get_rdfs_rel_path()); } if (!@rename($tmpfile_name, $newFile->get_full_path())) { return xmlrpcs_resperror(13, 'Error while writing to file.'); } // chmod the file $newFile->chmod(); // Initializes file properties (type, size, perms...) $newFile->load_properties(); // Load meta data AND MAKE SURE IT IS CREATED IN DB: $newFile->meta == 'unknown'; $newFile->load_meta(true); // Resize and rotate logIO('Running file post-processing (resize and rotate)...'); prepare_uploaded_files(array($newFile)); logIO('Done'); $url = $newFile->get_url(); logIO('URL of new file: ' . $url); $struct = new xmlrpcval(array('file' => new xmlrpcval($filename, 'string'), 'url' => new xmlrpcval($url, 'string'), 'type' => new xmlrpcval($file_mimetype, 'string')), 'struct'); logIO('OK.'); return new xmlrpcresp($struct); }
/** * wp.getOptions * * @see http://codex.wordpress.org/XML-RPC_wp#wp.getOptions * * Note: If passing in a struct, search for options listed within it. * * @param xmlrpcmsg XML-RPC Message * 0 blogid (int): Unique identifier of the blog. * 1 username (string): User login. * 2 password (string): Password for said username. * 3 options (struct) */ function wp_getoptions($m) { global $Settings; // CHECK LOGIN: /** * @var User */ if (!($current_User =& xmlrpcs_login($m, 1, 2))) { // Login failed, return (last) error: return xmlrpcs_resperror(); } // GET BLOG: /** * @var Blog */ if (!($Blog =& xmlrpcs_get_Blog($m, 0))) { // Login failed, return (last) error: return xmlrpcs_resperror(); } if (isset($m->params[3])) { $options = $m->getParam(3); $options = xmlrpc_decode_recurse($options); } $defaults = array('software_name' => array('desc' => 'Software Name', 'value' => 'WordPress'), 'software_version' => array('desc' => 'Software Version', 'value' => '3.3.2'), 'blog_url' => array('desc' => 'Site URL', 'value' => $Blog->gen_blogurl()), 'blog_title' => array('desc' => 'Site TitleL', 'value' => $Blog->get('name')), 'blog_tagline' => array('desc' => 'Site Tagline', 'value' => $Blog->get('tagline')), 'date_format' => array('desc' => 'Date Format', 'value' => locale_datefmt()), 'time_format' => array('desc' => 'Time Format', 'value' => locale_timefmt()), 'users_can_register' => array('desc' => 'Allow new users to sign up', 'value' => $Settings->get('newusers_canregister')), 'thumbnail_crop' => array('desc' => 'Crop thumbnail to exact dimensions', 'value' => false), 'thumbnail_size_w' => array('desc' => 'Thumbnail Width', 'value' => '160'), 'thumbnail_size_h' => array('desc' => 'Thumbnail Height', 'value' => '160'), 'medium_size_w' => array('desc' => 'Medium size image width', 'value' => '320'), 'medium_size_h' => array('desc' => 'Medium size image height', 'value' => '320'), 'large_size_w' => array('desc' => 'Large size image width', 'value' => '720'), 'large_size_h' => array('desc' => 'Large size image height', 'value' => '500')); $data = array(); if (empty($options)) { // No specific options where asked for, return all of them foreach ($defaults as $k => $opt) { $data[$k] = new xmlrpcval(array('desc' => new xmlrpcval($opt['desc']), 'readonly' => new xmlrpcval(true, 'boolean'), 'value' => new xmlrpcval($opt['value'])), 'struct'); } logIO('Retrieving all options'); } else { foreach ($options as $k) { if (!isset($defaults[$k])) { continue; } $data[$k] = new xmlrpcval(array('desc' => new xmlrpcval($defaults[$k]['desc']), 'readonly' => new xmlrpcval(true, 'boolean'), 'value' => new xmlrpcval($defaults[$k]['value'])), 'struct'); logIO('Retrieving option: ' . $k); } } logIO('OK.'); return new xmlrpcresp(new xmlrpcval($data, 'struct')); }
/** * Request abuse list from central blacklist. * * @return boolean true = success, false = error */ function antispam_poll_abuse() { global $Messages, $Settings, $baseurl, $debug, $antispamsrv_host, $antispamsrv_port, $antispamsrv_uri; // Construct XML-RPC client: load_funcs('xmlrpc/model/_xmlrpc.funcs.php'); $client = new xmlrpc_client($antispamsrv_uri, $antispamsrv_host, $antispamsrv_port); $client->debug = $debug; // Get datetime from last update, because we only want newer stuff... $last_update = $Settings->get('antispam_last_update'); // Encode it in the XML-RPC format $Messages->add(T_('Latest update timestamp') . ': ' . $last_update, 'note'); $startat = mysql2date('Ymd\\TH:i:s', $last_update); //$startat = iso8601_encode( mktime(substr($m,11,2),substr($m,14,2),substr($m,17,2),substr($m,5,2),substr($m,8,2),substr($m,0,4)) ); // Construct XML-RPC message: $message = new xmlrpcmsg('b2evo.pollabuse', array(new xmlrpcval(0, 'int'), new xmlrpcval('annonymous', 'string'), new xmlrpcval('nopassrequired', 'string'), new xmlrpcval($startat, 'dateTime.iso8601'), new xmlrpcval(0, 'int'))); $Messages->add(sprintf(T_('Requesting abuse list from %s...'), $antispamsrv_host), 'note'); $result = $client->send($message); if ($ret = xmlrpc_logresult($result, $Messages)) { // Response is not an error, let's process it: $response = $result->value(); if ($response->kindOf() == 'struct') { // Decode struct: $response = xmlrpc_decode_recurse($response); if (!isset($response['strings']) || !isset($response['lasttimestamp'])) { $Messages->add(T_('Incomplete reponse.'), 'error'); $ret = false; } else { // Start registering strings: $value = $response['strings']; if (count($value) == 0) { $Messages->add(T_('No new blacklisted strings are available.'), 'note'); } else { // We got an array of strings: $Messages->add(T_('Adding strings to local blacklist:'), 'note'); foreach ($value as $banned_string) { if (antispam_create($banned_string, 'central')) { // Creation successed $Messages->add(T_('Adding:') . ' «' . $banned_string . '»: ' . T_('OK.'), 'note'); } else { // Was already handled $Messages->add(T_('Adding:') . ' «' . $banned_string . '»: ' . T_('Not necessary! (Already handled)'), 'note'); antispam_update_source($banned_string, 'central'); } } // Store latest timestamp: $endedat = date('Y-m-d H:i:s', iso8601_decode($response['lasttimestamp'])); $Messages->add(T_('New latest update timestamp') . ': ' . $endedat, 'note'); $Settings->set('antispam_last_update', $endedat); $Settings->dbupdate(); } $Messages->add(T_('Done.'), 'success'); } } else { $Messages->add(T_('Invalid reponse.'), 'error'); $ret = false; } } return $ret; }
function check_updates() { global $Settings, $servertimenow, $app_version; $check_every = 86400 * 7; // check every 7 days $last_checked = $Settings->get('sonorth_last_checked'); if ($last_checked > $servertimenow - $check_every) { return false; } $Settings->set('sonorth_last_checked', $servertimenow); $Settings->dbupdate(); // Construct XML-RPC client: load_funcs('xmlrpc/model/_xmlrpc.funcs.php'); $client = new xmlrpc_client('/xmlrpc.php', 'rpc.sonorth.com', 80); $info = new xmlrpcval(array('product' => new xmlrpcval(str_replace('_Skin', '', get_class($this))), 'version' => new xmlrpcval($this->version), 'app_type' => new xmlrpcval('b2evolution'), 'add_version' => new xmlrpcval($app_version)), 'struct'); $message = new xmlrpcmsg('check_update.skin', array($info)); if (($result = $client->send($message)) && !$result->faultCode()) { $value = xmlrpc_decode_recurse($result->value()); if (is_array($value) && count($value) > 1) { if (!empty($value['version']) && version_compare($value['version'], $this->version)) { // There's a newer version available return $value; } } } return false; }
/** * Get updates from b2evolution.net * * @return boolean True if there have been updates. */ function b2evonet_get_updates() { global $DB, $debug, $evonetsrv_host, $evonetsrv_port, $evonetsrv_uri, $servertimenow, $evo_charset; global $Messages, $Settings, $baseurl, $instance_name, $app_name, $app_version, $app_date; $update_every = 3600 * 12; // 12 hours $attempt_every = 3600 * 4; // 4 hours /* DEBUG: * $update_every = 10; $attempt_every = 5; */ $servertime_last_update = $Settings->get('evonet_last_update'); if ($servertime_last_update > $servertimenow - $update_every) { // The previous update was less than 12 hours ago, skip this // echo 'recent update'; return false; } $servertime_last_attempt = $Settings->get('evonet_last_attempt'); if ($servertime_last_attempt > $servertimenow - $attempt_every) { // The previous update attempt was less than 4 hours ago, skip this // This is so all b2evo's don't go crazy if the server ever is down // echo 'recent attempt'; return false; } if ($debug) { $Messages->add(T_('Getting updates from ') . $evonetsrv_host, 'notes'); } $Settings->set('evonet_last_attempt', $servertimenow); $Settings->dbupdate(); // Construct XML-RPC client: load_funcs('xmlrpc/model/_xmlrpc.funcs.php'); $client = new xmlrpc_client($evonetsrv_uri, $evonetsrv_host, $evonetsrv_port); // $client->debug = $debug; // Run system checks: load_funcs('tools/model/_system.funcs.php'); list($mediadir_status) = system_check_media_dir(); list($uid, $uname) = system_check_process_user(); list($gid, $gname) = system_check_process_group(); // Construct XML-RPC message: $message = new xmlrpcmsg('b2evo.getupdates', array(new xmlrpcval($baseurl, 'string'), new xmlrpcval($instance_name, 'string'), new xmlrpcval($app_name, 'string'), new xmlrpcval($app_version, 'string'), new xmlrpcval($app_date, 'string'), new xmlrpcval(array('this_update' => new xmlrpcval($servertimenow, 'string'), 'last_update' => new xmlrpcval($servertime_last_update, 'string'), 'db_version' => new xmlrpcval($DB->get_version(), 'string'), 'db_utf8' => new xmlrpcval(system_check_db_utf8() ? 1 : 0, 'int'), 'evo_charset' => new xmlrpcval($evo_charset, 'string'), 'php_version' => new xmlrpcval(PHP_VERSION, 'string'), 'php_xml' => new xmlrpcval(extension_loaded('xml') ? 1 : 0, 'int'), 'php_mbstring' => new xmlrpcval(extension_loaded('mbstring') ? 1 : 0, 'int'), 'php_memory' => new xmlrpcval(system_check_memory_limit(), 'int'), 'php_upload_max' => new xmlrpcval(system_check_upload_max_filesize(), 'int'), 'php_post_max' => new xmlrpcval(system_check_post_max_size(), 'int'), 'mediadir_status' => new xmlrpcval($mediadir_status, 'string'), 'install_removed' => new xmlrpcval(system_check_install_removed() ? 1 : 0, 'int'), 'php_uid' => new xmlrpcval($uid, 'int'), 'php_uname' => new xmlrpcval($uname, 'string'), 'php_gid' => new xmlrpcval($gid, 'int'), 'php_gname' => new xmlrpcval($gname, 'string'), 'php_reg_globals' => new xmlrpcval(ini_get('register_globals') ? 1 : 0, 'int'), 'gd_version' => new xmlrpcval(system_check_gd_version(), 'string')), 'struct'))); $result = $client->send($message); if ($ret = xmlrpc_logresult($result, $Messages, false)) { // Response is not an error, let's process it: $response = $result->value(); if ($response->kindOf() == 'struct') { // Decode struct: $response = xmlrpc_decode_recurse($response); /** * @var AbstractSettings */ global $global_Cache; if (isset($response['evo_links'])) { // Extract evo links into its own var: $evo_links = $response['evo_links']; unset($response['evo_links']); if (is_array($evo_links)) { // Save creds: $global_Cache->set('evo_links', serialize($evo_links)); } } if (isset($response['creds'])) { // Extract creds into its own var: $creds = $response['creds']; unset($response['creds']); if (is_array($creds)) { // Save creds: $global_Cache->set('creds', serialize($creds)); } } // Save other info: $global_Cache->set('evonet_updates', serialize($response)); $global_Cache->dbupdate(); $Settings->set('evonet_last_update', $servertimenow); $Settings->dbupdate(); return true; } else { $Messages->add(T_('Invalid updates received'), 'error'); } } return false; }
} // ---------------------------------------------------------------------------------------------------- echo '<h2>blogger.newPost</h2>'; evo_flush(); $post_text = 'XML-RPC post : random # ' . rand(1, 10000); echo 'Post_text : ' . $post_text; $client->debug = 0; $content = "<title><i>{$post_text}</title>\n\t\t\t\t\t\t\t\t<p>{$post_text}</p>\n"; $content .= '<category>2,03</category>'; $message = new xmlrpcmsg('blogger.newPost', array(new xmlrpcval($bloggerAPIappkey), new xmlrpcval(1), new xmlrpcval($test_user), new xmlrpcval($test_pass), new xmlrpcval($content), new xmlrpcval(true, 'boolean'))); $result = $client->send($message); $ret = xmlrpc_displayresult($result); if (empty($ret)) { die('ERROR'); } $msg_ID = xmlrpc_decode_recurse($result->value()); echo '<p>OK - Message ID: ' . $msg_ID . '</p>'; // ---------------------------------------------------------------------------------------------------- echo '<h2>metaWeblog.getRecentPosts</h2>'; evo_flush(); $client->debug = 0; $message = new xmlrpcmsg('metaWeblog.getRecentPosts', array(new xmlrpcval(1), new xmlrpcval($test_user), new xmlrpcval($test_pass), new xmlrpcval(5, 'int'))); $result = $client->send($message); $ret = xmlrpc_displayresult($result); //pre_dump( $ret ); if (is_array($ret)) { foreach ($ret as $a) { echo '<li>' . htmlspecialchars($a['title']) . '</li>'; } } // ----------------------------------------------------------------------------------------------------
/** * metaWeblog.editPost * * @see http://www.xmlrpc.com/metaWeblogApi#basicEntrypoints * * @param xmlrpcmsg XML-RPC Message * 0 postid (string): Unique identifier of the post to edit * 1 username (string): Login for a Blogger user who has permission to edit the given * post (either the user who originally created it or an admin of the blog). * 2 password (string): Password for said username. * 3 struct (struct) * 4 publish (bool) * @param string item type 'post' or 'page' */ function mw_editpost($m, $item_type = 'post') { // CHECK LOGIN: /** * @var User */ if (!($current_User =& xmlrpcs_login($m, 1, 2))) { // Login failed, return (last) error: return xmlrpcs_resperror(); } // GET POST: /** * @var Item */ if (!($edited_Item =& xmlrpcs_get_Item($m, 0))) { // Failed, return (last) error: return xmlrpcs_resperror(); } // We need to be able to edit this post: if (!$current_User->check_perm('item_post!CURSTATUS', 'edit', false, $edited_Item)) { return xmlrpcs_resperror(3); // Permission denied } $xcontent = $m->getParam(3); $contentstruct = xmlrpc_decode_recurse($xcontent); logIO('Decoded xcontent'); if (isset($m->params[4])) { // getParam(4) is a flag for publish or draft $xstatus = $m->getParam(4); $xstatus = $xstatus->scalarval(); $status = $xstatus ? 'published' : 'draft'; // might be overrided later } $cat_IDs = _mw_get_cat_IDs($contentstruct, $edited_Item->get_Blog(), true); $date = _mw_decode_date($contentstruct); if (!empty($contentstruct['post_type']) && $contentstruct['post_type'] != $item_type) { // Overwrite from struct $item_type = $contentstruct['post_type']; } // Don't overwrite if not set $tags = isset($contentstruct['mt_keywords']) ? $contentstruct['mt_keywords'] : NULL; $content = isset($contentstruct['description']) ? $contentstruct['description'] : NULL; $excerpt = isset($contentstruct['mt_excerpt']) ? $contentstruct['mt_excerpt'] : NULL; $urltitle = isset($contentstruct['wp_slug']) ? $contentstruct['wp_slug'] : NULL; $parent_ID = isset($contentstruct['wp_page_parent_id']) ? $contentstruct['wp_page_parent_id'] : NULL; $author_ID = isset($contentstruct['wp_author_id']) ? $contentstruct['wp_author_id'] : NULL; $featured = isset($contentstruct['sticky']) ? $contentstruct['sticky'] : NULL; $order = isset($contentstruct['wp_page_order']) ? $contentstruct['wp_page_order'] : NULL; $custom_fields = isset($contentstruct['custom_fields']) ? $contentstruct['custom_fields'] : NULL; $item_typ_ID = isset($contentstruct['wp_post_format']) ? $contentstruct['wp_post_format'] : NULL; if (isset($contentstruct[$item_type . '_status'])) { $status = wp_or_b2evo_item_status($contentstruct[$item_type . '_status'], 'b2evo'); } if (isset($content_struct['mt_text_more'])) { // Add content extension $content .= '<!--more-->' . $content_struct['mt_text_more']; } //logIO( "Item content:\n".$content ); if (!empty($content_struct['enclosure']) && is_array($content_struct['enclosure'])) { // Add content extension $enclosure = $content_struct['enclosure']; if (isset($enclosure['url']) && isset($enclosure['length']) && isset($enclosure['type'])) { logIO("Item enclosure\n" . var_export($enclosure, true)); // TODO: sam2kb> Handle enclosures } } $comment_status = ''; // Don't overwrite if not set if (isset($contentstruct['mt_allow_comments'])) { if (!$contentstruct['mt_allow_comments'] || in_array($contentstruct['mt_allow_comments'], array(2, 'closed'))) { // Comments disabled $comment_status = 'disabled'; } else { $comment_status = 'open'; } } $params = array('title' => $contentstruct['title'], 'content' => $content, 'cat_IDs' => $cat_IDs, 'status' => $status, 'date' => $date, 'tags' => $tags, 'excerpt' => $excerpt, 'item_typ_ID' => $item_typ_ID, 'comment_status' => $comment_status, 'urltitle' => $urltitle, 'parent_ID' => $parent_ID, 'author_ID' => $author_ID, 'featured' => $featured, 'order' => $order, 'custom_fields' => $custom_fields); // COMPLETE VALIDATION & INSERT: return xmlrpcs_edit_item($edited_Item, $params); /* // Time to perform trackbacks NB NOT WORKING YET // // NB Requires a change to the _trackback library // // function trackbacks( $post_trackbacks, $content, $post_title, $post_ID ) // first extract these from posting as post_trackbacks array, then rest is easy // <member> // <name>mt_tb_ping_urls</name> // <value><array><data> // <value><string>http://archive.scripting.com/2005/04/17</string></value> // </data></array></value> // </member> // First check that trackbacks are allowed - mt_allow_pings $trackback_ok = 0; $trackbacks = array(); $trackback_ok = $contentstruct['mt_allow_pings']; logIO("Trackback OK ...".$trackback_ok); if ($trackback_ok == 1) { $trackbacks = $contentstruct['mt_tb_ping_urls']; logIO("Trackback url 0 ...".$trackbacks[0]); $no_of_trackbacks = count($trackbacks); logIO("Number of Trackbacks ...".$no_of_trackbacks); if ($no_of_trackbacks > 0) { logIO("Calling Trackbacks ..."); load_funcs('comments/_trackback.funcs.php'); $result = trackbacks( $trackbacks, $content, $post_title, $post_ID ); logIO("Returned from Trackbacks ..."); } } */ }
/** * metaWeblog.editPost (metaWeblog.editPost) * * @see http://www.xmlrpc.com/metaWeblogApi#basicEntrypoints * * @todo Tor - TODO * - Sort out sql select with blog ID * - screws up posts with multiple categories * partly due to the fact that Movable Type calls to this API are different to Metaweblog API calls when handling categories. * * @param xmlrpcmsg XML-RPC Message * 0 postid (string): Unique identifier of the post to edit * Currently ignored in b2evo, in favor of the category. * 1 username (string): Login for a Blogger user who has permission to edit the given * post (either the user who originally created it or an admin of the blog). * 2 password (string): Password for said username. * 3 struct (struct) */ function mw_editpost($m) { global $xmlrpcerruser; // import user errcode value global $DB; global $Settings; global $Messages; // CHECK LOGIN: /** * @var User */ if (!($current_User =& xmlrpcs_login($m, 1, 2))) { // Login failed, return (last) error: return xmlrpcs_resperror(); } // GET POST: /** * @var Item */ if (!($edited_Item =& xmlrpcs_get_Item($m, 0))) { // Failed, return (last) error: return xmlrpcs_resperror(); } $xstatus = $m->getParam(4); $xstatus = $xstatus->scalarval(); $status = $xstatus ? 'published' : 'draft'; logIO("Publish: {$xstatus} -> Status: {$status}"); $xcontent = $m->getParam(3); $contentstruct = xmlrpc_decode_recurse($xcontent); logIO("Decoded xcontent"); // Categories: $cat_IDs = _mw_get_cat_IDs($contentstruct, $edited_Item->blog_ID, true); if (!is_array($cat_IDs)) { // error: return $cat_IDs; } if (empty($cat_IDs)) { // TODO: make this finer // CHECK PERMISSION: (we need perm on current status) if (!$current_User->check_perm('blog_post!' . $status, 'edit', false, $edited_Item->blog_ID)) { // Permission denied return xmlrpcs_resperror(3); // User error 3 } $main_cat = NULL; } else { // CHECK PERMISSION: (we need perm on all categories, especially if they are in different blogs) if (!$current_User->check_perm('cats_post!' . $status, 'edit', false, $cat_IDs)) { // Permission denied return xmlrpcs_resperror(3); // User error 3 } $main_cat = $cat_IDs[0]; } logIO('Permission granted.'); $post_date = _mw_decode_postdate($contentstruct, false); $post_title = $contentstruct['title']; $content = $contentstruct['description']; // COMPLETE VALIDATION & UPDATE: return xmlrpcs_edit_item($edited_Item, $post_title, $content, $post_date, $main_cat, $cat_IDs, $status); /* // Time to perform trackbacks NB NOT WORKING YET // // NB Requires a change to the _trackback library // // function trackbacks( $post_trackbacks, $content, $post_title, $post_ID ) // first extract these from posting as post_trackbacks array, then rest is easy // <member> // <name>mt_tb_ping_urls</name> // <value><array><data> // <value><string>http://archive.scripting.com/2005/04/17</string></value> // </data></array></value> // </member> // First check that trackbacks are allowed - mt_allow_pings $trackback_ok = 0; $trackbacks = array(); $trackback_ok = $contentstruct['mt_allow_pings']; logIO("Trackback OK ...".$trackback_ok); if ($trackback_ok == 1) { $trackbacks = $contentstruct['mt_tb_ping_urls']; logIO("Trackback url 0 ...".$trackbacks[0]); $no_of_trackbacks = count($trackbacks); logIO("Number of Trackbacks ...".$no_of_trackbacks); if ($no_of_trackbacks > 0) { logIO("Calling Trackbacks ..."); load_funcs('comments/_trackback.funcs.php'); $result = trackbacks( $trackbacks, $content, $post_title, $post_ID ); logIO("Returned from Trackbacks ..."); } } */ }
/** * Get updates from b2evolution.net * * @param boolean useful when trying to upgrade to a release that has just been published (in the last 12 hours) * @return NULL|boolean True if there have been updates, false on error, * NULL if the user has turned off updates. */ function b2evonet_get_updates($force_short_delay = false) { global $allow_evo_stats; // Possible values: true, false, 'anonymous' global $DB, $debug, $evonetsrv_host, $evonetsrv_port, $evonetsrv_uri, $servertimenow, $evo_charset; global $Messages, $Settings, $baseurl, $instance_name, $app_name, $app_version, $app_date; global $Debuglog; global $Timer; if (!isset($allow_evo_stats)) { // Set default value: $allow_evo_stats = true; // allow (non-anonymous) stats } if ($allow_evo_stats === false) { // Get outta here: return NULL; } if ($debug == 2) { $update_every = 8; $attempt_every = 3; } elseif ($force_short_delay) { $update_every = 180; // 3 minutes $attempt_every = 60; // 1 minute } else { $update_every = 3600 * 12; // 12 hours $attempt_every = 3600 * 4; // 4 hours } // Note: do not put $baseurl in here since it would cause too frequently updates, when you have the same install with different $baseurls. // Everytime this method gets called on another baseurl, there's a new check for updates! $version_id = $instance_name . ' ' . $app_name . ' ' . $app_version . ' ' . $app_date; // This is the last version we checked against the server: $last_version_checked = $Settings->get('evonet_last_version_checked'); $servertime_last_update = $Settings->get('evonet_last_update'); $servertime_last_attempt = $Settings->get('evonet_last_attempt'); if ($last_version_checked == $version_id) { // Current version has already been checked, don't check too often: if ($servertime_last_update > $servertimenow - $update_every) { // The previous update was less than 12 hours ago, skip this // echo 'recent update'; return false; } if ($servertime_last_attempt > $servertimenow - $attempt_every) { // The previous update attempt was less than 4 hours ago, skip this // This is so all b2evo's don't go crazy if the server ever is down // echo 'recent attempt'; return false; } } $Timer->resume('evonet: check for updates'); $Debuglog->add(sprintf('Getting updates from %s.', $evonetsrv_host), 'evonet'); if ($debug) { $Messages->add(sprintf(T_('Getting updates from %s.'), $evonetsrv_host), 'note'); } $Settings->set('evonet_last_attempt', $servertimenow); $Settings->dbupdate(); // Construct XML-RPC client: load_funcs('xmlrpc/model/_xmlrpc.funcs.php'); $client = new xmlrpc_client($evonetsrv_uri, $evonetsrv_host, $evonetsrv_port); if ($debug > 1) { $client->debug = 1; } // Run system checks: load_funcs('tools/model/_system.funcs.php'); // Get system stats to display: $system_stats = get_system_stats(); // Construct XML-RPC message: $message = new xmlrpcmsg('b2evo.getupdates', array(new xmlrpcval($allow_evo_stats === 'anonymous' ? md5($baseurl) : $baseurl, 'string'), new xmlrpcval($instance_name, 'string'), new xmlrpcval($app_name, 'string'), new xmlrpcval($app_version, 'string'), new xmlrpcval($app_date, 'string'), new xmlrpcval(array('this_update' => new xmlrpcval($servertimenow, 'string'), 'last_update' => new xmlrpcval($servertime_last_update, 'string'), 'mediadir_status' => new xmlrpcval($system_stats['mediadir_status'], 'int'), 'install_removed' => new xmlrpcval($system_stats['install_removed'] == 'ok' ? 1 : 0, 'int'), 'evo_charset' => new xmlrpcval($system_stats['evo_charset'], 'string'), 'evo_blog_count' => new xmlrpcval($system_stats['evo_blog_count'], 'int'), 'cachedir_status' => new xmlrpcval($system_stats['cachedir_status'], 'int'), 'cachedir_size' => new xmlrpcval($system_stats['cachedir_size'], 'int'), 'general_pagecache_enabled' => new xmlrpcval($system_stats['general_pagecache_enabled'] ? 1 : 0, 'int'), 'blog_pagecaches_enabled' => new xmlrpcval($system_stats['blog_pagecaches_enabled'], 'int'), 'db_version' => new xmlrpcval($system_stats['db_version'], 'string'), 'db_utf8' => new xmlrpcval($system_stats['db_utf8'] ? 1 : 0, 'int'), 'php_uid' => new xmlrpcval($system_stats['php_uid'], 'int'), 'php_uname' => new xmlrpcval($system_stats['php_uname'], 'string'), 'php_gid' => new xmlrpcval($system_stats['php_gid'], 'int'), 'php_gname' => new xmlrpcval($system_stats['php_gname'], 'string'), 'php_version' => new xmlrpcval($system_stats['php_version'], 'string'), 'php_reg_globals' => new xmlrpcval($system_stats['php_reg_globals'] ? 1 : 0, 'int'), 'php_allow_url_include' => new xmlrpcval($system_stats['php_allow_url_include'] ? 1 : 0, 'int'), 'php_allow_url_fopen' => new xmlrpcval($system_stats['php_allow_url_fopen'] ? 1 : 0, 'int'), 'php_upload_max' => new xmlrpcval($system_stats['php_upload_max'], 'int'), 'php_post_max' => new xmlrpcval($system_stats['php_post_max'], 'int'), 'php_memory' => new xmlrpcval($system_stats['php_memory'], 'int'), 'php_mbstring' => new xmlrpcval($system_stats['php_mbstring'] ? 1 : 0, 'int'), 'php_xml' => new xmlrpcval($system_stats['php_xml'] ? 1 : 0, 'int'), 'php_imap' => new xmlrpcval($system_stats['php_imap'] ? 1 : 0, 'int'), 'php_opcode_cache' => new xmlrpcval($system_stats['php_opcode_cache'], 'string'), 'gd_version' => new xmlrpcval($system_stats['gd_version'], 'string')), 'struct'))); $result = $client->send($message); if ($ret = xmlrpc_logresult($result, $Messages, false)) { // Response is not an error, let's process it: $response = $result->value(); if ($response->kindOf() == 'struct') { // Decode struct: $response = xmlrpc_decode_recurse($response); /** * @var AbstractSettings */ global $global_Cache; foreach ($response as $key => $data) { $global_Cache->set($key, serialize($data)); } $global_Cache->delete('evonet_updates'); // Cleanup $global_Cache->dbupdate(); $Settings->set('evonet_last_update', $servertimenow); $Settings->set('evonet_last_version_checked', $version_id); $Settings->dbupdate(); $Debuglog->add('Updates saved', 'evonet'); $Timer->pause('evonet: check for updates'); return true; } else { $Debuglog->add('Invalid updates received', 'evonet'); $Messages->add(T_('Invalid updates received'), 'error'); } } $Timer->pause('evonet: check for updates'); return false; }