Alphred
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Todo
  • Download

Namespaces

  • Alphred
  • None

Classes

  • Alphred
  1 <?php
  2 /**
  3  * Contains Config class for Alphred
  4  *
  5  * PHP version 5
  6  *
  7  * @package    Alphred
  8  * @copyright  Shawn Patrick Rice 2014
  9  * @license    http://opensource.org/licenses/MIT  MIT
 10  * @version    1.0.0
 11  * @author     Shawn Patrick Rice <rice@shawnrice.org>
 12  * @link       http://www.github.com/shawnrice/alphred
 13  * @link       http://shawnrice.github.io/alphred
 14  * @since      File available since Release 1.0.0
 15  *
 16  */
 17 
 18 namespace Alphred;
 19 
 20 /**
 21  * A simple class to manage configuration for workflows
 22  *
 23  * Currently, there are three handlers that are available: `json`, `sqlite`, and
 24  * `ini`. These correspond to their obvious data storage types. To use, do something
 25  * simple like:
 26  * ````php
 27  * $config = new Alphred\Config( 'ini' );
 28  * $config->set( 'username', 'shawn patrick rice' );
 29  * ````
 30  * To get it later, just use:
 31  * ````php
 32  * $username = $config->read( 'username' );
 33  * ````
 34  *
 35  * You can store arrays and more complex data with the `json` and `ini` handlers.
 36  * Currently, the SQLite3 handler is a bit primitive.
 37  *
 38  */
 39 class Config {
 40 
 41     /**
 42      * A list of valid handlers and their file extensions
 43      *
 44      * Current options are `json`, `sqlite`, and `ini`.
 45      *
 46      * @since 1.0.0
 47      *
 48      * @var array
 49      */
 50     private $handlers = [
 51         // as file_extension => handler_name
 52         'json'      => 'json',
 53         'sqlite3' => 'sqlite',
 54         'ini'       => 'ini',
 55     ];
 56 
 57     /**
 58      * Constructs the Config object
 59      *
 60      * @since 1.0.0
 61      * @todo Make this pluggable (to load custom handlers)
 62      *
 63      * @param string $handler  the name of the handler
 64      * @param string $filename the basename of the config file
 65      */
 66     public function __construct( $handler, $filename = 'config' ) {
 67 
 68         // Do a quick check to make sure that we're running in a workflow environment
 69         // because we need access to certain variables for this to work
 70         if ( ! Globals::bundle() ) {
 71             throw new RunningOutsideOfAlfred( "Cannot use Alphred's Config outside of the workflow environment", 4 );
 72         }
 73         // Make sure that the data directory has been created
 74         self::create_data_directory();
 75 
 76         if ( ! in_array( $handler, $this->handlers ) ) {
 77             /**
 78              * @todo Redo the exception
 79              */
 80             throw new Exception( "Unknown config handler: {$handler}", 4 );
 81         }
 82 
 83         // Set the handler
 84         $this->handler = $handler;
 85         // Construct the filename
 86         $this->filename = $filename . '.' . array_search( $handler, $this->handlers );
 87         // Load the handler
 88         $this->load_handler( $this->handler );
 89 
 90     }
 91 
 92 
 93     /**
 94      * Creates the data directory
 95      *
 96      * @throws \Alphred\RunningOutsideOfAlfred
 97      *
 98      * @return bool Whether or not the directory was created or exists
 99      */
100     private function create_data_directory() {
101         // Get the data directory from the Globals array
102         if ( $dir = Globals::data() ) {
103             // If the directory does not exist, then make it
104             if ( ! file_exists( $dir ) ) {
105                 // Debug-level log message
106                 \Alphred\Log::log( "Creating data directory.", 0, 'debug' );
107 
108                 // Make the directory
109                 return mkdir( $dir, 0775, true );
110             } else {
111                 // Directory exists, so return true
112                 return true;
113             }
114         }
115         // The workflow_data
116         throw new RunningOutsideOfAlfred( "Cannot use Alphred's Config outside of the workflow environment", 4 );
117     }
118 
119     /**
120      * Gets the path for the config file
121      *
122      * @since 1.0.0
123      *
124      * @return string       path to config file
125      */
126     private function get_config_file() {
127         return Globals::data() . '/' . $this->filename;
128     }
129 
130     /*****************************************************************************
131      * Generic Handler Wrapper Functions
132      ****************************************************************************/
133 
134     /**
135      * Loads a handler
136      *
137      * @since 1.0.0
138      *
139      * @param  string $handler the name of the handler
140      * @return bool            success of loading the handler
141      */
142     private function load_handler( $handler ) {
143         $method = 'load_' . $this->handler;
144         \Alphred\Log::console( 'Loading config file `' . $this->get_config_file() . '`', 0 );
145         return $this->$method();
146     }
147 
148     /**
149      * Sets a value in the config
150      *
151      * @since 1.0.0
152      *
153      * @param  string $key    the key to set
154      * @param  mixed  $value  the value to set
155      * @return bool                     success as true/false
156      */
157     public function set( $key, $value ) {
158         $method = 'set_' . $this->handler;
159         return $this->$method( $key, $value );
160     }
161 
162     /**
163      * Reads a value from the config
164      *
165      * @since 1.0.0
166      *
167      * @param  string $key   the key to read
168      * @return mixed         the values for the key
169      */
170     public function read( $key ) {
171         $method = 'read_' . $this->handler;
172         return $this->$method( $key );
173     }
174 
175     /**
176      * Unsets a value from the config
177      *
178      * Note: I would name this `unset`, but that's a reserved function name.
179      *
180      * @since 1.0.0
181      *
182      * @param  string   $key    the name of the key
183      * @return boolean
184      */
185     public function delete( $key ) {
186         $method = 'unset_' . $this->handler;
187         return $this->$method( $key );
188     }
189 
190     /*****************************************************************************
191      * JSON Handler
192      ****************************************************************************/
193 
194     /**
195      * Loads the json handler
196      *
197      * @since 1.0.0
198      *
199      * @return boolean success if handler was loaded
200      */
201     private function load_json() {
202         if ( ! file_exists( $this->get_config_file() ) ) {
203             file_put_contents( $this->get_config_file(), [] );
204         }
205         $this->config = json_decode( file_get_contents( $this->get_config_file() ), true );
206         return true;
207     }
208 
209     /**
210      * Sets a config value
211      *
212      * @since 1.0.0
213      *
214      * @param string $key    the name of the key
215      * @param mixed  $value  the value of the key
216      * @return boolean success
217      */
218     private function set_json( $key, $value ) {
219         // Reload the json file
220         $this->load_json();
221         $this->config[ $key ] = $value;
222         return file_put_contents( $this->get_config_file(), json_encode( $this->config ) );
223     }
224 
225     /**
226      * Reads a config value
227      *
228      * @since 1.0.0
229      *
230      * @param  string $key the key to read
231      * @return mixed       the value of the key
232      */
233     private function read_json( $key ) {
234         if ( isset( $this->config[ $key ] ) ) {
235             return $this->config[ $key ];
236         }
237         throw new ConfigKeyNotSet( "`{$key}` is not set.", 1 );
238     }
239 
240     /**
241      * Unsets a config value
242      *
243      * @since 1.0.0
244      *
245      * @param  string $key the key to unset
246      * @return boolean     true if the key existed; false if the key did not exist
247      */
248     private function unset_json( $key ) {
249         if ( ! isset( $this->config[ $key ] ) ) {
250             return false;
251         }
252         unset( $this->config[ $key ] );
253         file_put_contents( $this->get_config_file(), json_encode( $this->config ) );
254         return true;
255     }
256 
257     /*****************************************************************************
258      * SQLite3 Handler
259      ****************************************************************************/
260 
261     /**
262      * Loads the SQLite3 handler
263      *
264      * @since 1.0.0
265      *
266      * @return boolean true on success
267      */
268     private function load_sqlite() {
269         $this->db = new \SQLite3( $this->get_config_file() );
270         $this->init_db_table();
271         return true;
272     }
273 
274     /**
275      * Creates the database table
276      *
277      * @return boolean true on success
278      */
279     private function init_db_table() {
280         return $this->db->exec(
281           'CREATE TABLE IF NOT EXISTS config (key TEXT NOT NULL PRIMARY KEY, value TEXT) WITHOUT ROWID;'
282         );
283     }
284 
285     /**
286      * Sets a config value
287      *
288      * @since 1.0.0
289      *
290      * @param  string $key   the name of the key
291      * @param  mixed  $value the value to set
292      * @return boolean success
293      */
294     private function set_sqlite( $key, $value, $overwrite = true ) {
295         $key   = $this->db->escapeString( $key );
296         $value = $this->db->escapeString( $value );
297         if ( $overwrite ) {
298             $this->db->exec( "DELETE FROM config WHERE key='{$key}';" );
299         }
300         $query = "INSERT OR REPLACE INTO config (key, value) values ('{$key}', '{$value}');";
301         return $this->db->exec( $query );
302     }
303 
304     /**
305      * Reads a config value
306      *
307      * @since 1.0.0
308      *
309      * @param  string $key the key to read
310      * @return mixed       the value of the key
311      */
312     private function read_sqlite( $key ) {
313         $query = $this->db->prepare( 'SELECT * FROM config WHERE key=:key' );
314         $query->bindValue( ':key', $key, SQLITE3_TEXT );
315         $result = $query->execute();
316         // the assumption is that there will be only one row
317         $result = $result->fetchArray( SQLITE3_ASSOC );
318         if ( isset( $result[ 'value' ] ) ) {
319             return $result['value'];
320         }
321         throw new ConfigKeyNotSet( "`{$key}` is not set.", 1 );
322     }
323 
324     /**
325      * Deletes a value from the config
326      *
327      * @since 1.0.0
328      *
329      * @param  string $key  the key to delete
330      * @return boolean      success
331      */
332     private function unset_sqlite( $key ) {
333         $key = $this->db->escapeString( $key );
334         return $this->db->exec( "DELETE FROM config WHERE key = '{$key}';" );
335     }
336 
337     /*****************************************************************************
338      * Ini Handler
339      ****************************************************************************/
340 
341     /**
342      * Loads the ini handler
343      *
344      * @since 1.0.0
345      * @see Ini INI functionality
346      *
347      * @return bool     true on success
348      */
349     private function load_ini() {
350         // Check if the file exists
351         if ( ! file_exists( $this->get_config_file() ) ) {
352             // Create an empty config file since none exists
353             Ini::write_ini( [], $this->get_config_file() );
354         }
355         // Load the config
356         $this->config = Ini::read_ini( $this->get_config_file() );
357         return true;
358     }
359 
360     /**
361      * Sets a config value
362      *
363      * @since 1.0.0
364      * @see Ini INI functionality
365      *
366      * @param string $key   the key to set
367      * @param mixed $value the value to set
368      */
369     private function set_ini( $key, $value ) {
370         // Re-initialize the config variable
371         $this->load_ini();
372         // Set the key
373         $this->config[ $key ] = $value;
374         // Write the INI file
375         return Ini::write_ini( $this->config, $this->get_config_file() );
376     }
377 
378     /**
379      * Reads a value from a config file
380      *
381      * @since 1.0.0
382      * @see Ini INI functionality
383      * @throws \Alphred\ConfigKeyNotSet when the key is not set
384      *
385      * @param  string $key the key to read
386      * @return mixed       the value of the key
387      */
388     private function read_ini( $key ) {
389         // Re-initialize the config variable
390         $this->config = Ini::read_ini( $this->get_config_file() );
391         if ( isset( $this->config[ $key ] ) ) {
392             return $this->config[ $key ];
393         }
394         // If the config key is not sent, throw an exception rather than returning false
395         throw new ConfigKeyNotSet( "`{$key}` is not set.", 1 );
396     }
397 
398     /**
399      * Unsets a config
400      *
401      * @since 1.0.0
402      * @see Ini INI functionality
403      *
404      * @param  string $key the key to unset
405      * @return boolean     true if the key existed; false if the key did not exist
406      */
407     private function unset_ini( $key ) {
408         // Re-initialize the config variable
409         $this->config = Ini::read_ini( $this->get_config_file() );
410         if ( isset( $this->config[ $key ] ) ) {
411             unset( $this->config[ $key ] );
412             Ini::write_ini( $this->config, $this->get_config_file() );
413             return true;
414         }
415         return false;
416     }
417 
418 }
419 
420 
421 
Alphred API documentation generated by ApiGen