Services_Blogging
[ class tree: Services_Blogging ] [ index: Services_Blogging ] [ all elements ]

Source for file LiveJournal.php

Documentation is available at LiveJournal.php

  1. <?php
  2. require_once 'Services/Blogging/ExtendedDriver.php';
  3. require_once 'Services/Blogging/Driver/Exception.php';
  4. require_once 'Services/Blogging/XmlRpc.php';
  5. require_once 'XML/RPC.php';
  6.  
  7. /**
  8. * LiveJournal API implementation.
  9. *
  10. * This class implements the LiveJournal XML-RPC API described at
  11. * http://www.livejournal.com/doc/server/ljp.csp.xml-rpc.protocol.html
  12. *
  13. @category Services
  14. @package  Services_Blogging
  15. @author   Christian Weiske <cweiske@php.net>
  16. @license  http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  17. @link     http://pear.php.net/package/Services_Blogging
  18. */
  19. {
  20.     /**
  21.     * Requests shall be sent to here
  22.     */
  23.     const XML_RPC_SERVER = 'http://www.livejournal.com';
  24.     const XML_RPC_PATH   = '/interface/xmlrpc';
  25.  
  26.     /**
  27.     * Internal list with user data.
  28.     * @var array 
  29.     */
  30.     protected $userdata                  = array();
  31.  
  32.     protected $arSupportedPostProperties = array(
  33.         Services_Blogging_Post::TITLE,
  34.         Services_Blogging_Post::CONTENT,
  35.         Services_Blogging_Post::DATE,
  36.         Services_Blogging_Post::URL,
  37.     );
  38.  
  39.  
  40.  
  41.     /**
  42.     * Constructor for the LiveJournal driver.
  43.     *
  44.     * If $server and $path are set to NULL, the default
  45.     *  blogger.com address is used.
  46.     *
  47.     * @param string $user   The username of the blog account.
  48.     * @param string $pass   The password of the blog account.
  49.     * @param string $server The URI of the server to connect to.
  50.     * @param string $path   The path to the XML-RPC server script.
  51.     *
  52.     * @throws Services_Blogging_Exception If authentication fails
  53.     */
  54.     public function __construct($user$pass$server = null$path = null)
  55.     {
  56.         if ($server === null{
  57.             $server = self::XML_RPC_SERVER;
  58.             $path   = self::XML_RPC_PATH;
  59.         }
  60.         $this->userdata = array(
  61.             'user'      => $user,
  62.             'pass'      => $pass,
  63.             'server'    => $server,
  64.             'path'      => $path,
  65.             'rpc_user'  => new XML_RPC_Value($user'string'),
  66.             'rpc_pass'  => new XML_RPC_Value($pass'string'),
  67.         );
  68.  
  69.  
  70.         $this->rpc_client = new XML_RPC_Client(
  71.             $this->userdata['path'],
  72.             $this->userdata['server']
  73.         );
  74.  
  75.         $authdata     $this->getAuthData();
  76.         $authenticate = new XML_RPC_Message(
  77.             'LJ.XMLRPC.login',
  78.             array(
  79.                 new XML_RPC_Value(
  80.                     array(
  81.                         'username'       => $this->userdata['rpc_user'],
  82.                         'auth_method'    => new XML_RPC_Value('challenge''string'),
  83.                         'auth_challenge' => new XML_RPC_Value($authdata['challenge']'string'),
  84.                         'auth_response'  => new XML_RPC_Value($authdata['response''string'),
  85.                         'clientversion'  => new XML_RPC_Value('PHP-Services_Blogging/0.0.1')
  86.                     ),
  87.                     'struct'
  88.                 )
  89.             )
  90.         );
  91.         Services_Blogging_XmlRpc::sendRequest($authenticate$this->rpc_client);
  92.     }//public function __construct($userid, $pass, $server = null, $path = null)
  93.  
  94.  
  95.  
  96.     protected function md5_hex($string)
  97.     {
  98.         $md5 md5($stringtrue);//raw output
  99.         $hex '';
  100.         for ($nC = 0; $nC strlen($md5)$nC++{
  101.             $hex .= str_pad(dechex(ord($md5[$nC]))2'0'STR_PAD_LEFT);
  102.         }
  103.         return $hex;
  104.     }//protected function md5_hex($string)
  105.  
  106.  
  107.  
  108.     protected function getAuthData()
  109.     {
  110.         //get challenge for authentication
  111.         $authenticate = new XML_RPC_Message('LJ.XMLRPC.getchallenge'array());
  112.         $response     Services_Blogging_XmlRpc::sendRequest(
  113.             $authenticate$this->rpc_client
  114.         );
  115.  
  116.         return array(
  117.             'challenge' => $response['challenge'],
  118.             'response'  => $this->md5_hex(
  119.                 $response['challenge'$this->md5_hex($this->userdata['pass'])
  120.             )
  121.         );
  122.     }//protected function getAuthData()
  123.  
  124.  
  125.  
  126.     /**
  127.     * Save a new post into the blog.
  128.     *
  129.     * @param Services_Blogging_Post $post Post object to put online
  130.     *
  131.     * @return void 
  132.     *
  133.     * @throws Services_Blogging_Exception If an error occured
  134.     */
  135.     public function savePost(Services_Blogging_Post $post)
  136.     {
  137.         $authdata $this->getAuthData();
  138.  
  139.         $time $post->{Services_Blogging_Post::DATE};
  140.         if ($time == ''  || $time == 0{
  141.             $time = time();
  142.         }
  143.  
  144.         if ($post->id === null{
  145.             //post is new and has no Id => create new one
  146.             $request = new XML_RPC_Message('LJ.XMLRPC.postevent',
  147.                 array(
  148.                     new XML_RPC_Value(
  149.                         array(
  150.                             'username'       => $this->userdata['rpc_user'],
  151.                             'auth_method'    => new XML_RPC_Value('challenge''string'),
  152.                             'auth_challenge' => new XML_RPC_Value($authdata['challenge']'string'),
  153.                             'auth_response'  => new XML_RPC_Value($authdata['response''string'),
  154.  
  155.                             'subject'        => new XML_RPC_Value($post->{Services_Blogging_Post::TITLE}),
  156.                             'event'          => new XML_RPC_Value($post->{Services_Blogging_Post::CONTENT}),
  157.                             'lineendings'    => new XML_RPC_Value('pc'),
  158.  
  159.                             'year'           => new XML_RPC_Value(date('Y'$time)'int'),
  160.                             'mon'            => new XML_RPC_Value(date('n'$time)'int'),
  161.                             'day'            => new XML_RPC_Value(date('j'$time)'int'),
  162.                             'hour'           => new XML_RPC_Value(date('G'$time)'int'),
  163.                             'min'            => new XML_RPC_Value(date('i'$time)'int'),
  164.                         ),
  165.                         'struct'
  166.                     )
  167.                 )
  168.             );
  169.  
  170.             $arData Services_Blogging_XmlRpc::sendRequest(
  171.                 $request$this->rpc_client
  172.             );
  173.             $post->setId($arData['itemid']);
  174.             $post->{Services_Blogging_Post::URL$arData['url'];
  175.         else {
  176.             //edit the post; it already exists
  177.             $request = new XML_RPC_Message('LJ.XMLRPC.editevent',
  178.                 array(
  179.                     new XML_RPC_Value(
  180.                         array(
  181.                             'username'       => $this->userdata['rpc_user'],
  182.                             'auth_method'    => new XML_RPC_Value('challenge''string'),
  183.                             'auth_challenge' => new XML_RPC_Value($authdata['challenge']'string'),
  184.                             'auth_response'  => new XML_RPC_Value($authdata['response''string'),
  185.  
  186.                             'itemid'         => new XML_RPC_Value($post->id'int'),
  187.  
  188.                             'subject'        => new XML_RPC_Value($post->{Services_Blogging_Post::TITLE}),
  189.                             'event'          => new XML_RPC_Value($post->{Services_Blogging_Post::CONTENT}),
  190.                             'lineendings'    => new XML_RPC_Value('pc'),
  191.  
  192.                             'year'           => new XML_RPC_Value(date('Y'$time)'int'),
  193.                             'mon'            => new XML_RPC_Value(date('n'$time)'int'),
  194.                             'day'            => new XML_RPC_Value(date('j'$time)'int'),
  195.                             'hour'           => new XML_RPC_Value(date('G'$time)'int'),
  196.                             'min'            => new XML_RPC_Value(date('i'$time)'int'),
  197.                         ),
  198.                         'struct'
  199.                     )
  200.                 )
  201.             );
  202.  
  203.             $arData Services_Blogging_XmlRpc::sendRequest(
  204.                 $request$this->rpc_client
  205.             );
  206.         }
  207.     }//public function savePost(Services_Blogging_Post $post)
  208.  
  209.  
  210.  
  211.     /**
  212.     * Delete a given post.
  213.     *
  214.     * @param mixed $post Services_Blogging_Post object to delete,
  215.     *                      or post id (integer) to delete
  216.     *
  217.     * @return boolean True if deleted, false if not.
  218.     */
  219.     public function deletePost($post)
  220.     {
  221.         if (!($post instanceof Services_Blogging_Post)) {
  222.             $nPostId $post;
  223.             $post    = new Services_Blogging_Post();
  224.             $post->setId($nPostId);
  225.         }
  226.         /**
  227.         * In LiveJournal, posts are deleted by emptying
  228.         * some fields
  229.         */
  230.         $post->{Services_Blogging_Post::CONTENT'';
  231.         $post->{Services_Blogging_Post::TITLE}   '';
  232.         $post->{Services_Blogging_Post::DATE}    = 0;
  233.  
  234.         return $this->savePost($post);
  235.     }//public function deletePost($post)
  236.  
  237.  
  238.  
  239.     /**
  240.     * The getPost method is intended to retrieve a given post as an object of
  241.     * the Services_Blogging_Post class; given the unique post id which is passed
  242.     * as a parameter to the function.
  243.     *
  244.     * @param string $id The PostID of the post to be retrieved.
  245.     *
  246.     * @return Services_Blogging_Post The elements of the post returned as an
  247.     *                                 object of the Services_Blogging_Post class.
  248.     *
  249.     * @throws Services_Blogging_Exception If the post does not exist
  250.     */
  251.     public function getPost($id)
  252.     {
  253.         $authdata $this->getAuthData();
  254.         $request  = new XML_RPC_Message('LJ.XMLRPC.getevents',
  255.             array(
  256.                 new XML_RPC_Value(
  257.                     array(
  258.                         'username'       => $this->userdata['rpc_user'],
  259.                         'auth_method'    => new XML_RPC_Value('challenge''string'),
  260.                         'auth_challenge' => new XML_RPC_Value($authdata['challenge']'string'),
  261.                         'auth_response'  => new XML_RPC_Value($authdata['response''string'),
  262.  
  263.                         'selecttype'     => new XML_RPC_Value('one''string'),
  264.                         'itemid'         => new XML_RPC_Value($id'int')
  265.                     ),
  266.                     'struct'
  267.                 )
  268.             )
  269.         );
  270.  
  271.         $arData Services_Blogging_XmlRpc::sendRequest(
  272.             $request$this->rpc_client
  273.         );
  274.         if (count($arData['events']== 0{
  275.             throw new Services_Blogging_Driver_Exception(
  276.                 'Post does not exist'self::ERROR_POSTDOESNTEXIST
  277.             );
  278.         }
  279.  
  280.         return $this->convertStructToPost(reset($arData['events']));
  281.     }//public function getPost($id)
  282.  
  283.  
  284.  
  285.     /**
  286.     * Returns an array of recent posts as Services_Blogging_Post objects
  287.     *
  288.     * @param int $number The number of posts to be retrieved.
  289.     *                      Defaults to 15
  290.     *
  291.     * @return Array An array of objects of the Services_Blogging_Post class that
  292.     *                 correspond to the number of posts requested.
  293.     */
  294.     public function getRecentPosts($number = 15)
  295.     {
  296.         if ($number > 50{
  297.             $number = 50;
  298.         }
  299.  
  300.         $authdata $this->getAuthData();
  301.         $request  = new XML_RPC_Message('LJ.XMLRPC.getevents',
  302.             array(
  303.                 new XML_RPC_Value(
  304.                     array(
  305.                         'username'       => $this->userdata['rpc_user'],
  306.                         'auth_method'    => new XML_RPC_Value('challenge''string'),
  307.                         'auth_challenge' => new XML_RPC_Value($authdata['challenge']'string'),
  308.                         'auth_response'  => new XML_RPC_Value($authdata['response''string'),
  309.  
  310.                         'selecttype'     => new XML_RPC_Value('lastn''string'),
  311.                         'howmany'        => new XML_RPC_Value($number'int')
  312.                     ),
  313.                     'struct'
  314.                 )
  315.             )
  316.         );
  317.  
  318.         $arData Services_Blogging_XmlRpc::sendRequest(
  319.             $request$this->rpc_client
  320.         );
  321.         $arPosts = array();
  322.         foreach ($arData['events'as $event{
  323.             $post               $this->convertStructToPost($event);
  324.             $arPosts[$post->id$post;
  325.         }
  326.  
  327.         return $arPosts;
  328.     }//public function getRecentPosts($number = 15)
  329.  
  330.  
  331.  
  332.     /**
  333.     * The getRecentPostTitles method is intended to retrieve the given number of
  334.     * post titles from a blog.
  335.     * The posts themselves can be retrieved with getPost() or getPosts().
  336.     *
  337.     * @param int $number The number of posts to be retrieved.
  338.     *
  339.     * @return Array An array of int => strings representing the
  340.     *                 post ids (key) and their title (value).
  341.     */
  342.     public function getRecentPostTitles($number = 15)
  343.     {
  344.         if ($number > 50{
  345.             $number = 50;
  346.         }
  347.  
  348.         $authdata $this->getAuthData();
  349.         $request  = new XML_RPC_Message('LJ.XMLRPC.getevents',
  350.             array(
  351.                 new XML_RPC_Value(
  352.                     array(
  353.                         'username'       => $this->userdata['rpc_user'],
  354.                         'auth_method'    => new XML_RPC_Value('challenge''string'),
  355.                         'auth_challenge' => new XML_RPC_Value($authdata['challenge']'string'),
  356.                         'auth_response'  => new XML_RPC_Value($authdata['response''string'),
  357.  
  358.                         'selecttype'     => new XML_RPC_Value('lastn''string'),
  359.                         'howmany'        => new XML_RPC_Value($number'int'),
  360.                         'prefersubject'  => new XML_RPC_Value(true'boolean'),
  361.                         'truncate'       => new XML_RPC_Value(50'string'),
  362.                         'noprops'        => new XML_RPC_Value(true'boolean')
  363.                     ),
  364.                     'struct'
  365.                 )
  366.             )
  367.         );
  368.  
  369.         $arData Services_Blogging_XmlRpc::sendRequest(
  370.             $request$this->rpc_client
  371.         );
  372.         $arTitles = array();
  373.         foreach ($arData['events'as $event{
  374.             $arTitles[$event['itemid']] $event['event'];
  375.         }
  376.  
  377.         return $arTitles;
  378.     }//public function getRecentPostTitles($number = 15)
  379.  
  380.  
  381.  
  382.     /**
  383.     * Returns an array of strings thay define
  384.     * the properties that a post to this blog may
  385.     * have.
  386.     *
  387.     * @param string $strPostType Type of post to create.
  388.     *                            @see getSupportedPostTypes()
  389.     *
  390.     * @return array Array of strings
  391.     */
  392.     public function getSupportedPostProperties($strPostType 'post')
  393.     {
  394.         return $this->arSupportedPostProperties;
  395.     }//public function getSupportedPostProperties(..)
  396.  
  397.  
  398.  
  399.     /**
  400.     * Checks if the given property name/id is supported
  401.     * for this driver.
  402.     *
  403.     * @param string $strProperty Property name/id to check
  404.     * @param string $strPostType Type of post to create.
  405.     *                            @see getSupportedPostTypes()
  406.     *
  407.     * @return boolean If the property is supported
  408.     */
  409.     public function isPostPropertySupported($strProperty$strPostType 'post')
  410.     {
  411.         return in_array($strProperty$this->arSupportedPostProperties);
  412.     }//public function isPostPropertySupported(..)
  413.  
  414.  
  415.  
  416.     /**
  417.     * Converts a struct returned by the webservice to
  418.     * a Services_Blogging_Post object
  419.     *
  420.     * @param array $arStruct Struct to convert
  421.     *
  422.     * @return Services_Blogging_Post Converted post
  423.     */
  424.     protected function convertStructToPost($arStruct)
  425.     {
  426.         $post = new Services_Blogging_Post($this);
  427.  
  428.         $post->{Services_Blogging_Post::CONTENT$arStruct['event'];
  429.         $post->{Services_Blogging_Post::TITLE}   $arStruct['subject'];
  430.         //0123456789012345678
  431.         //2006-05-13 21:42:00
  432.         $post->{Services_Blogging_Post::DATEmktime(
  433.             substr($arStruct['eventtime']112)//hour
  434.             substr($arStruct['eventtime']142)//minute
  435.             substr($arStruct['eventtime']172)//second
  436.             substr($arStruct['eventtime'],  52)//month
  437.             substr($arStruct['eventtime'],  82)//day
  438.             substr($arStruct['eventtime'],  04)  //year
  439.         );
  440.         $post->{Services_Blogging_Post::URL$arStruct['url'];
  441.         $post->setId($arStruct['itemid']);
  442.  
  443.         return $post;
  444.     }//protected function convertStructToPost($arStruct)
  445.  
  446. }//class Services_Blogging_Driver_Blogger
  447. ?>

Documentation generated on Mon, 11 Mar 2019 15:25:12 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.