home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / Services / Blogging / Driver / LiveJournal.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  16.0 KB  |  449 lines

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