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

Documentation generated on Mon, 11 Mar 2019 14:57:58 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.