• Hello,

    I created a tool to manage a huge amount of blogs. This tool should also be able to scedule Postings. I saw that the metaWeblog.newPost command has the fields ‘dateCreated’ and ‘date_created_gmt’. If i assign a Date to it, i get no response from the xmlrpc.php. I figured out that it might be an error at the following code:

    starting at line 2183:

    // Do some timestamp voodoo
    		if ( !empty( $content_struct['date_created_gmt'] ) )
    			$dateCreated = str_replace( 'Z', '', $content_struct['date_created_gmt']->getIso() ) . 'Z'; // We know this is supposed to be GMT, so we're going to slap that Z on there by force
    		elseif ( !empty( $content_struct['dateCreated']) )
    			$dateCreated = $content_struct['dateCreated']->getIso();

    $content_struct[‘dateCreated’] and $content_struct[‘date_created_gmt’] are NOT objects, they are just an sting, so the call of ->getIso() fails.

    I removed the ->getIso() and the Post will be storred at database, but not marked as sceduled. It will be posted, with a date in future… how to fix it.

    Or short: How i can scedule a Post using XMLRPC / metaWeblog.newPost

    I hope anyone of u can help me solve this Problem. I dont want do store future posts at a database and post it by a cronjob.

    greetings

    Alexander Kurtz

Viewing 10 replies - 1 through 10 (of 10 total)
  • Thread Starter akurtz

    (@akurtz)

    I found a way to solve my problem, but i had to fix the xmlrpc.php, thats a thing i wount do, because i have to fix it at more than 250 worpressinstallations ?? .

    I fixed at the Mothod: mw_newPost($args), starting at line 2007

    1st fix: starting at line 2105

    if( isset( $content_struct["{$post_type}_status"] ) ) {
    			switch( $content_struct["{$post_type}_status"] ) {
    				case 'draft':
    				case 'private':
    				case 'publish':
    				case 'future': # <-- ADDED THIS LINE
    					$post_status = $content_struct["{$post_type}_status"];
    					break;
    				case 'pending':
    					// Pending is only valid for posts, not pages.
    					if( $post_type === 'post' ) {
    						$post_status = $content_struct["{$post_type}_status"];
    					}
    					break;
    				default:
    					$post_status = $publish ? 'publish' : 'draft';
    					break;
    			}
    		}

    2nd fix: starting at line 2203

    remove the call off non existing Method ->getIso()

    // Do some timestamp voodoo
    		if ( !empty( $content_struct['date_created_gmt'] ) )
    		{
    			$dateCreated = str_replace( 'Z', '', $content_struct['date_created_gmt']/*->getIso()*/ ) . 'Z'; // We know this is supposed to be GMT, so we're going to slap that Z on there by force
    
    		}elseif ( !empty( $content_struct['dateCreated']) ){
    			$dateCreated = $content_struct['dateCreated']/*->getIso()*/;
    		}

    In my code i add 2 fields $content-array if its in future:

    if (strtotime($_REQUEST['form']['dateCreated']) > time()) {
    	$content['post_status'] 	= 'future';
    	$publish			= 0;
    }

    so my XML will look like:

    <methodCall>
    <methodName>metaWeblog.newPost</methodName>
    
    <params>
    <param>
    <value>
    <array>
    <data>
    <value>USERNAME
    <string></string>
    </value>USERNAME
    
    <value>
    <string>{YOUR-WP-USERNAME-HERE}</string>
    </value>
    
    <value>
    <string>{YOUR-WP-PASSWORD-HERE}</string>
    </value>
    
    <value>
    <struct>
    <member>
    <name>wp_slug</name>
    
    <value>
    <string></string>
    </value>
    </member>
    
    <member>
    <name>wp_password</name>
    
    <value>USERNAME
    <string></string>
    </value>
    </member>
    
    <member>
    <name>wp_author_id</name>
    
    <value>
    <string></string>
    </value>
    </member>
    
    <member>
    <name>title</name>
    USERNAME
    <value>
    <string>Test of sceduled Posting</string>USERNAME
    </value>
    </member>
    
    <member>
    <name>description</name>
    
    <value>
    <string><p>Test of sceduled Posting</p></string>
    </value>
    </member>
    
    <member>
    <name>mt_excerpt</name>
    
    <value>
    <string><p>Test of sceduled Posting</p></string>
    </value>
    </member>
    
    <member>USERNAME
    <name>mt_text_more</name>
    
    <value>
    <string></string>
    </value>USERNAME
    </member>
    
    <member>
    <name>mt_allow_comments</name>
    
    <value>
    <string></string>
    </value>
    </member>
    
    <member>
    <name>mt_allow_pings</name>
    
    <value>
    <string></string>USERNAME
    </value>
    </member>USERNAME
    
    <member>
    <name>date_created_gmt</name>
    
    <value>
    <string>2009-12-11 13:00:00</string>
    </value>
    </member>
    
    <member>
    <name>post_status</name>
    
    <value>USERNAME
    <string>future</string>
    </value>
    </member>
    </struct>
    </value>
    
    <value>
    <int>0</int>
    </value>
    </data>
    </array>
    </value>
    </param>USERNAME
    </params>
    </methodCall>

    I gues there is no other way to solve this problem, until an offical fix will be released.

    I hope this will help others with same problem.

    greetings

    Alexander Kurtz

    Thread Starter akurtz

    (@akurtz)

    Damm, i figured out that’s not all to fix, the Posts will have no _gmt-Dates in database and so WP think the schedule was missed, an posts them…

    So how to set the _gmt-dates at the xmlrpc.php ???

    why this is not completly correctly written ????

    Your XML-RPC request is using the wrong data type for dates:

    <member>
    <name>date_created_gmt</name>
    
    <value>
    <string>2009-12-11 13:00:00</string>
    </value>
    </member>

    You are providing the server with a string type instead of a dateTime.iso8601 type – https://www.xmlrpc.com/spec

    Thread Starter akurtz

    (@akurtz)

    Hi joseph scott,

    did u tried by urself?

    i found out not the correct format for the date_created_gmt

    <member>
    <name>date_created_gmt</name>
    
    <value>
    
    <string>20091113T12:30:00Z</string>
    </value>
    </member>

    but if i post on a unfixed blog, i got nothing as response.

    var_dump() of my result just says NULL.

    in my eys this lines are responsable for that:

    // Do some timestamp voodoo
    		if ( !empty( $content_struct['date_created_gmt'] ) )
    			$dateCreated = str_replace( 'Z', '', $content_struct['date_created_gmt']->getIso() ) . 'Z'; // We know this is supposed to be GMT, so we're going to slap that Z on there by force
    		elseif ( !empty( $content_struct['dateCreated']) )
    			$dateCreated = $content_struct['dateCreated']->getIso();
    
    		if ( !empty( $dateCreated ) ) {
    			$post_date = get_date_from_gmt(iso8601_to_datetime($dateCreated));
    			$post_date_gmt = iso8601_to_datetime($dateCreated, GMT);
    		} else {
    			$post_date     = $postdata['post_date'];
    			$post_date_gmt = $postdata['post_date_gmt'];
    		}

    how can $content_struct['dateCreated']->getIso() work when $content_struct['dateCreated'] is of type string???

    this will result in a php-error. so i will get no return value… and the post will not added to the database.

    wenn i remove the ->getIso() all will work fine. the post is added to the database, but as not as future… so i have to add an case 'future': at this lines:

    switch( $content_struct["{$post_type}_status"] ) {
    				case 'draft':
    				case 'private':
    				case 'publish':
    					$post_status = $content_struct["{$post_type}_status"];
    					break;
    				case 'pending':
    					// Pending is only valid for posts, not pages.
    					if( $post_type === 'post' ) {
    						$post_status = $content_struct["{$post_type}_status"];
    					}
    					break;
    				default:
    					$post_status = $publish ? 'publish' : 'draft';
    					break;
    			}

    then all will work fine, when my client adds

    <member>
    <name>post_status</name>
    
    <value>
    <string>future</string>
    </value>
    </member>

    to the struct.

    After doing this i can post a scheduled post using XML-RPC.

    In my oppinion this should be fixed soon in the next WP release …

    or anyone can explain me how it will work, without this fixes ??

    Dates in XML-RPC are not string types, they have a type of dateTime.iso8601. So the snippet of XML should look like:

    <member>
    <name>date_created_gmt</name>
    
    <value>
    <dateTime.iso8601>20091113T12:30:00Z</dateTime.iso8601>
    </value>
    </member>

    This is per the XML-RPC spec that I linked to previously – https://www.xmlrpc.com/spec

    I added the date_created_gmt field because there was such confusion (and in some cases poor support in XML-RPC libraries) for dateCreated and time zones. Any date in the date_created_gmt field is GMT, always, with or with out the trailing Z.

    Thread Starter akurtz

    (@akurtz)

    what XML-RPC library u are using?

    will the ->getIso() call work then??

    It doesn’t matter what XML-RPC library you are using, it needs to pass date values as a type of dateTime.iso8601.

    For the record I use the same IXR PHP library that WordPress does, it implements both client and server sides of XML-RPC.

    attuk

    (@attuk)

    Sorry to sound thick but how can I
    xmlrpc encode iso8601 dateTime to get

    <member>
    <name>date_created_gmt</name>

    <value>
    <dateTime.iso8601>20091113T12:30:00Z</dateTime.iso8601>
    </value>
    </member>

    My code is
    $content = array(
    ‘dateCreated’ => “<dateTime.iso8601>date(“c”)</dateTime.iso8601>”,
    );
    $params = array(0,$username,$password,$content,true);
    $request = xmlrpc_encode_request(‘metaWeblog.newPost’,$params);

    This keeps generating a Fatal error: Call to a member function getIso() on a non-object in xmlrpc.php on line 1564

    Thanks for any advice

    I had been under the same problem. But after reading your posts several times for 3-4 days, I came up with a solution, that you will not need to modify the code of xmlrpc.php. Practically that is not always possible.

    HERE IS THE SOLUTION
    ——————————————-
    Because it is necessary to have

    <dateTime.iso8601>20100825T08:30:00Z</dateTime.iso8601>

    type of tag in XML and the php script does not allow us t do that, simply create your response using XML string.

    $request = '<?xml version="1.0" encoding="iso-8859-1"?>
    <methodCall>
    <methodName>metaWeblog.newPost</methodName>
    <params>
     <param>
      <value>
       <int>1</int>
      </value>
     </param>
     <param>
    
      <value>
       <string>admin</string>
      </value>
     </param>
     <param>
      <value>
       <string>kabhi9901</string>
      </value>
    
     </param>
     <param>
      <value>
       <struct>
        <member>
         <name>title</name>
         <value>
          <string>Sample Post Title</string>
    
         </value>
        </member>
        <member>
         <name>description</name>
         <value>
          <string>This is a sample post.</string>
         </value>
        </member>
    
        <member>
         <name>date_created_gmt</name>
         <value>
          <strong><dateTime.iso8601>20100825T08:30:00Z</dateTime.iso8601></strong>
         </value>
        </member>
        <member>
         <name>categories</name>
    
         <value>
          <array>
           <data>
            <value>
             <string>Uncategorized</string>
            </value>
            <value>
             <string>History</string>
    
            </value>
           </data>
          </array>
         </value>
        </member>
       </struct>
      </value>
     </param>
     <param>
    
      <value>
       <boolean>1</boolean>
      </value>
     </param>
    </params>
    </methodCall>
    ';

    As you can see in this XML string, that <dateTime.iso8601> tag has been used. Now use this $response in making RPC call

    $xmlresponse = get_response($BLOGURL."/xmlrpc.php", $request);

    where get_response is this function

    function get_response($URL, $context) {
    	if(!function_exists('curl_init')) {
    		die ("Curl PHP package not installed\n");
    	}
    
    	/*Initializing CURL*/
    	$curlHandle = curl_init();
    
    	/*The URL to be downloaded is set*/
    	curl_setopt($curlHandle, CURLOPT_URL, $URL);
    	curl_setopt($curlHandle, CURLOPT_HEADER, false);
    	curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
    	curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $context);
    
    	/*Now execute the CURL, download the URL specified*/
    	$response = curl_exec($curlHandle);
    	return $response;
    }

    Use the PHP IXR library for XML-RPC requests, it takes care of these sorts of issues.

Viewing 10 replies - 1 through 10 (of 10 total)
  • The topic ‘How to scedule a Post using XMLRPC / metaWeblog.newPost ??’ is closed to new replies.