]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/Irc/extlib/phergie/Phergie/Plugin/Php/Source/Local.php
Added Phergie PHP IRC library
[quix0rs-gnu-social.git] / plugins / Irc / extlib / phergie / Phergie / Plugin / Php / Source / Local.php
1 <?php
2 /**
3  * Phergie 
4  *
5  * PHP version 5
6  *
7  * LICENSE
8  *
9  * This source file is subject to the new BSD license that is bundled
10  * with this package in the file LICENSE.
11  * It is also available through the world-wide-web at this URL:
12  * http://phergie.org/license
13  *
14  * @category  Phergie 
15  * @package   Phergie_Plugin_Php
16  * @author    Phergie Development Team <team@phergie.org>
17  * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
18  * @license   http://phergie.org/license New BSD License
19  * @link      http://pear.phergie.org/package/Phergie_Plugin_Php
20  */
21
22 /**
23  * Data source for {@see Phergie_Plugin_Php}. This source reads function 
24  * descriptions from a file and stores them in a SQLite database. When a 
25  * function description is requested, the function is retrieved from the 
26  * local database.
27  *
28  * @category Phergie 
29  * @package  Phergie_Plugin_Php
30  * @author   Phergie Development Team <team@phergie.org>
31  * @license  http://phergie.org/license New BSD License
32  * @link     http://pear.phergie.org/package/Phergie_Plugin_Php
33  * @uses     extension pdo 
34  * @uses     extension pdo_sqlite 
35  * @uses     Phergie_Plugin_Command pear.phergie.org
36  */
37 class Phergie_Plugin_Php_Source_Local implements Phergie_Plugin_Php_Source
38 {
39     /**
40      * Local database for storage
41      *
42      * @var PDO 
43      */
44     protected $database;
45
46     /**
47      * Source of the PHP function summary
48      *
49      * @var string
50      */
51     protected $url = 'http://cvs.php.net/viewvc.cgi/phpdoc/funcsummary.txt?revision=HEAD';
52
53     /**
54      * Constructor to initialize the data source.
55      *
56      * @return void
57      */
58     public function __construct()
59     {
60         $path = dirname(__FILE__);
61
62         try {
63             $this->database = new PDO('sqlite:' . $path . '/functions.db');
64             $this->buildDatabase();
65             // @todo Modify this to be rethrown as an appropriate 
66             //       Phergie_Plugin_Exception and handled in Phergie_Plugin_Php
67         } catch (PDOException $e) {
68         }
69     }
70
71     /**
72      * Searches for a description of the function.
73      * 
74      * @param string $function Search pattern to match against the function 
75      *        name, wildcards supported using %
76      *
77      * @return array|null Associative array containing the function name and 
78      *         description or NULL if no results are found
79      */
80     public function findFunction($function)
81     {
82         // Remove possible parentheses
83         $split = preg_split('{\(|\)}', $function);
84         $function = (count($split)) ? array_shift($split) : $function;
85
86         // Prepare the database statement
87         $stmt = $this->database->prepare('SELECT `name`, `description` FROM `functions` WHERE `name` LIKE :function');
88         $stmt->execute(array(':function' => $function));
89
90         // Check the results
91         if (count($stmt) > 0) {
92             $result = $stmt->fetch(PDO::FETCH_ASSOC);
93             /**
94              * @todo add class and function URLS
95              * class methods: http://php.net/manual/en/classname.methodname.php
96              * functions: http://php.net/manual/en/function.functionname.php
97              * where '_' is replaced with '-'
98              */
99             return $result;
100         }
101
102         // No results found, return
103         return null;
104     }
105
106     /**
107      * Build the database and parses the function summary file into it.
108      *
109      * @param bool $rebuild TRUE to force a rebuild of the table used to 
110      *        house function information, FALSE otherwise, defaults to FALSE
111      *
112      * @return void
113      */
114     protected function buildDatabase($rebuild = false)
115     {
116         // Check to see if the functions table exists
117         $table = $this->database->exec("SELECT COUNT(*) FROM `sqlite_master` WHERE `name` = 'functions'");
118
119         // If the table doesn't exist, create it
120         if (!$table) {
121             $this->database->exec('CREATE TABLE `functions` (`name` VARCHAR(255), `description` TEXT)');
122             $this->database->exec('CREATE UNIQUE INDEX `functions_name` ON `functions` (`name`)');
123         }
124
125         // If we created a new table, fill it with data
126         if (!$table || $rebuild) {
127             // Get the contents of the source file
128             // @todo Handle possible error cases better here; the @ operator 
129             //       shouldn't be needed
130             $contents = @file($this->url, FILE_IGNORE_NEW_LINES + FILE_SKIP_EMPTY_LINES);
131
132             if (!$contents) {
133                 return;
134             }
135
136             // Parse the contents
137             $valid = array();
138             $firstPart = '';
139             $lineNumber = 0;
140             foreach ($contents as $line) {
141                 // Clean the current line
142                 $line = trim($line);
143
144                 // Skip comment lines
145                 if (0 === strpos($line, '#')) {
146                     // reset the line if the current line is odd
147                     if (($lineNumber % 2) !== 0) {
148                         $lineNumber--;
149                     }
150                     continue;
151                 }
152
153                 /*
154                  * If the current line is even, it's the first part of the
155                  * complete function description ...
156                  */
157                 if (($lineNumber % 2) === 0) {
158                     $firstPart = $line;
159                 } else {
160                     // ... it's the last part of the complete function description
161                     $completeLine = $firstPart . ' ' . $line;
162                     $firstPart = '';
163                     if (preg_match('{^([^\s]*)[\s]?([^)]*)\(([^\)]*)\)[\sU]+([\sa-zA-Z0-9\.\-_]*)$}', $completeLine, $matches)) {
164                         $valid[] = $matches;
165                     }
166                 }
167                 // Up the line number before going to the next line
168                 $lineNumber++;
169             }
170             // free up some memory
171             unset($contents);
172
173             // Process the valid matches
174             if (count($valid) > 0) {
175                 // Clear the database
176                 $this->database->exec('DELETE * FROM `functions`');
177
178                 // Prepare the sql statement
179                 $stmt = $this->database->prepare('INSERT INTO `functions` (`name`, `description`) VALUES (:name, :description)');
180                 $this->database->beginTransaction();
181
182                 // Insert the data
183                 foreach ($valid as $function) {
184                     // Extract function values
185                     list( , $retval, $name, $params, $desc) = $function;
186                     if (empty($name)) {
187                         $name = $retval;
188                         $retval = '';
189                     }
190                     // Reconstruct the complete function line
191                     $line = trim($retval . ' ' . $name . '(' . $params . ') - ' . $desc);
192                     // Execute the statement
193                     $stmt->execute(array(':name' => $name, ':description' => $line));
194                 }
195                 
196                 // Commit the changes to the database
197                 $this->database->commit();
198             }
199             // free up some more memory
200             unset($valid);
201         }
202     }
203 }