Overview
  • Namespace
  • Class

Namespaces

  • yii2cdn

Classes

  • yii2cdn\Cdn
  • yii2cdn\Component
  • yii2cdn\ConfigFile
  • yii2cdn\ConfigLoader
  • yii2cdn\ConfigParser
  • yii2cdn\File
  • yii2cdn\Section
  1 <?php
  2 
  3 /**
  4  * @copyright Copyright (c) 2016 Junaid Atari
  5  * @link http://junaidatari.com Website
  6  * @see http://www.github.com/blacksmoke26/yii2-cdn
  7  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  8  */
  9 
 10 namespace yii2cdn;
 11 
 12 use yii\base\InvalidConfigException;
 13 use yii\base\UnknownPropertyException;
 14 use yii\base\InvalidParamException;
 15 use yii\helpers\ArrayHelper;
 16 
 17 defined('YII2CDN_OFFLINE') or define('YII2CDN_OFFLINE', false);
 18 
 19 /**
 20  * Yii2 CDN Component
 21  *
 22  * @package yii2cdn
 23  * @author Junaid Atari <mj.atari@gmail.com>
 24  *
 25  * @access public
 26  * @version 0.1
 27  */
 28 class Cdn extends \yii\base\Component {
 29 
 30     /**
 31      * Base url to cdn directory
 32      * @var string
 33      */
 34     public $baseUrl = null;
 35 
 36     /**
 37      * base path to cdn directory
 38      * @var string
 39      */
 40     public $basePath = null;
 41 
 42     /**
 43      * Custom url aliases, replaces with @alias(*) in files url
 44      * Usage:
 45      *  ['xyz' => '/url/to', ...]
 46      * @var array
 47      */
 48     public $aliases = [];
 49 
 50     /**
 51      * CDN component class
 52      * default: \yii2cdn\Component
 53      * @var string
 54      */
 55     public $componentClass = '\yii2cdn\Component';
 56 
 57     /**
 58      * CDN components configuration parser class
 59      * default: \yii2cdn\ComponentConfigParser
 60      * @var string
 61      */
 62     public $configParserClass = '\yii2cdn\ConfigParser';
 63 
 64     /**
 65      * CDN component section class
 66      * default: \yii2cdn\ComponentSection
 67      * @var string
 68      */
 69     public $sectionClass = '\yii2cdn\Section';
 70 
 71     /**
 72      * CDN Configuration File Class
 73      * default: \yii2cdn\ConfigFile
 74      * @var string
 75      */
 76     public $configFileClass = '\yii2cdn\ConfigFile';
 77 
 78     /**
 79      * CDN component section file class
 80      * default: \yii2cdn\SectionFile
 81      * @var string
 82      */
 83     public $fileClass = '\yii2cdn\File';
 84 
 85     /**
 86      * CDN component configuration loader class
 87      * default: \yii2cdn\ConfigLoader
 88      * @var string
 89      */
 90     public $configLoaderClass = '\yii2cdn\ConfigLoader';
 91 
 92     /**
 93      * CDN components configuration files list
 94      * Usage:
 95      *     1. 'path/to/cdn-config.php' : main file path
 96      *     2. ['path/to/cdn-config.php'] : main file path
 97      *     3. ['path/to/cdn-config.php', 'offline'=>false] : online cdn file path
 98      *     4. ['path/to/cdn-config.php', 'offline'=>true] : offline cdn file path
 99      * @var array
100      */
101     public $configs = [];
102 
103     /**
104      * CDN components configuration
105      * @var array
106      */
107     public $components = [];
108 
109     /**
110      * Sections name list
111      * default: (<code>css</code>, <code>js</code>)
112      * @var array
113      */
114     public $sections = ['js', 'css'];
115 
116     /**
117      * Cache Key for caching built components configuration to load fast
118      * @var string
119      */
120     public $cacheKey = null;
121 
122     /**
123      * Enable storing components configuration in cache
124      * @var boolean
125      */
126     public $enableCaching = false;
127 
128     /**
129      * Components registered under cdn
130      *
131      * @var array
132      */
133     protected $_regComponents = [];
134 
135     /**
136      * Component intializer
137      * @throws \yii\base\InvalidConfigException when property is empty
138      */
139     public function init () {
140         parent::init();
141 
142         foreach ( ['baseUrl', 'basePath'] as $prop ) {
143             if ( empty($this->$prop) ) {
144                 throw new InvalidConfigException("{$prop} property is empty");
145             }
146         }
147 
148         if ( $this->enableCaching && empty($this->cacheKey) ) {
149             throw new InvalidConfigException("cacheKey property is empty");
150         }
151 
152         // Build components
153         $this->buildComponentsCache();
154     }
155 
156     /**
157      * Get a ConfigFile Object
158      * @param string $file
159      * @return ConfigFile
160      */
161     protected function getFileConfigObject ( $file = null ) {
162         /** @var ConfigFile $fileConfig */
163         return \Yii::createObject($this->configFileClass, [ [
164             'path' => $file,
165             'componentClass' => $this->componentClass,
166             'configParserClass' => $this->configParserClass,
167             'configLoaderClass' => $this->configLoaderClass,
168             'fileClass' => $this->fileClass,
169             'sectionClass' => $this->sectionClass,
170             'basePath' => $this->basePath,
171             'baseUrl' => $this->baseUrl,
172             'aliases' => $this->aliases,
173             'sections' => $this->sections
174         ]]);
175     }
176 
177     /**
178      * Import components from configuration array
179      *
180      * @param array $config Components configuration
181      */
182     protected function loadComponents ( array $config ) {
183         /** @var ConfigFile $configFile */
184         $configFile = $this->getFileConfigObject ( null );
185 
186         $this->_regComponents = ArrayHelper::merge (
187             $this->_regComponents,
188             $configFile->get ( ( $config ) )
189         );
190     }
191 
192     /**
193      * Import components from configuration file
194      * @param string $path Components configuration file path
195      */
196     protected function loadComponentsFile ( $path ) {
197         /** @var ConfigFile $configFile */
198         $configFile = $this->getFileConfigObject( $path );
199 
200         $this->_regComponents = ArrayHelper::merge(
201             $this->_regComponents,
202             $configFile->get()
203         );
204     }
205 
206     /**
207      * Build a components list
208      */
209     protected function buildComponentsCache () {
210         if ( $this->enableCaching ) {
211 
212             $cached = \Yii::$app->cache->get ( $this->cacheKey );
213 
214             if ( $cached !== false ) {
215                 $this->_regComponents = $cached;
216                 return;
217             }
218         }
219 
220         // @property `components` : load CDN components config
221         if ( is_array($this->components) && !empty($this->components) ) {
222             $this->loadComponents($this->components);
223         }
224 
225         // @property `configs` : load CDN components config files
226         if ( is_array($this->configs) && !empty($this->configs) ) {
227 
228             foreach ( $this->configs as $cfg ) {
229 
230                 if ( empty($cfg)) {
231                     continue;
232                 }
233 
234                 $this->loadComponentsFile($cfg);
235             }
236         }
237 
238         if ( $this->enableCaching ) {
239             \Yii::$app->cache->set($this->cacheKey, $this->_regComponents);
240         }
241     }
242 
243     /**
244      * Remove the cache and rebuild components list
245      */
246     public function refresh () {
247         \Yii::$app->cache->delete( $this->cacheKey );
248         $this->buildComponentsCache();
249     }
250 
251     /**
252      * Check that Mode Live or Offline
253      *
254      * @return bool
255      */
256     public static function isOnline () {
257         return !defined ( 'YII2CDN_OFFLINE' ) ? true : !YII2CDN_OFFLINE;
258     }
259 
260     /**
261      * Get cdn component by ID
262      * @see Cdn::exists()
263      * @param string $id Component ID
264      * @return Component|null Component Object
265      */
266     public function get ( $id, $throwException = true ) {
267         if ( !$this->exists($id, $throwException) ) {
268             return null;
269         }
270 
271         return $this->_regComponents[$id];
272     }
273 
274     /**
275      * Check that cdn component exists
276      * @param string $id Component ID
277      * @param boolean $throwException (optional) Throw exception when unknown component id given (default: false)
278      * @throws \yii\base\UnknownPropertyException When unknown component id given
279      * @return boolean True when exist, False when undefined
280      */
281     public function exists ( $id, $throwException = true ) {
282         if ( !array_key_exists($id, $this->_regComponents) ) {
283             if ( $throwException ) {
284                 throw new UnknownPropertyException ("Unknown cdn component '{$id}'");
285             } else {
286                 return false;
287             }
288         }
289 
290         return true;
291     }
292 
293     /**
294      * Get the file by root
295      * Root example : component-id/section
296      *
297      * @see Component::get()
298      * @see Section::getSection()
299      * @param string $root Root to file
300      * @param bool $throwException True will throw exception (default: true)
301      * @throws \yii\base\UnknownPropertyException When unknown component id given
302      * @throws \yii\base\InvalidParamException When null given as section
303      * @throws \yii\base\UnknownPropertyException When section name not found
304      * @return \yii2cdn\Section Section Object
305      */
306     public function getSectionByRoot ( $root, $throwException = true ) {
307         // validate the root
308         if ( !is_string ( $root ) || substr_count ( $root, '/' ) != 1 ) {
309             throw new InvalidParamException ( "Invalid section root '{$root}' given" );
310         }
311 
312         list ( $componentId, $sectionId ) = explode ( '/', $root );
313 
314         return $this->get ( $componentId, $throwException )->getSection ( $sectionId, $throwException );
315     }
316 
317     /**
318      * Get the file by root
319      * Root example : component-id/section/file-id
320      * @see Component::get()
321      * @see Section::getSection()
322      * @see Section::getFileById()
323      * @param string $root Root to file
324      * @param bool $asUrl True will return file url instead of object (default: false)
325      * @param bool $throwException True will throw exception (default: true)
326      * @throws \yii\base\UnknownPropertyException When unknown component id given
327      * @throws \yii\base\InvalidParamException When null given as section
328      * @throws \yii\base\UnknownPropertyException When section name not found
329      * @throws \yii\base\UnknownPropertyException When file id not found
330      * @return \yii2cdn\File|string|null Section file | File Url | Null when not found
331      */
332     public function getFileByRoot ( $root, $asUrl = false, $throwException = true ) {
333         // validate the root
334         if ( !is_string($root) || substr_count($root, '/') != 2 ) {
335             throw new InvalidParamException ("Invalid file root '{$root}' given");
336         }
337 
338         list ($componentId, $sectionId, $fileId) = explode('/', $root);
339 
340         return $this->get($componentId, $throwException)->getFileByRoot( "$sectionId/$fileId", $asUrl, $throwException );
341     }
342 
343     /**
344      * Perform a callback function when Offline mode is active
345      * @see Cdn::isOnline()
346      * @param callable $callback A callback function
347      * <code>
348      *     function ( \yii2cdn\Cdn $cdn ) {
349      *         // some logic here
350      *     }
351      * </code>
352      * @param string $property (optional) Default component property name (default: cdn)
353      * @return Cdn
354      * @throws \yii\base\InvalidConfigException When the callback parameter is not a function
355      */
356     public function whenOffline ( $callback, $property = 'cdn' ) {
357 
358         if ( !is_callable($callback) ) {
359             throw new InvalidParamException ("Parameter '{callback}' should be a function");
360         }
361 
362         if ( !self::isOnline()  ) {
363             call_user_func_array( $callback, [\Yii::$app->get($property)] );
364         }
365 
366         return $this;
367     }
368 
369     /**
370      * Perform a callback function when Online mode is active
371      * @see Cdn::isOnline()
372      * @param callable $callback A callback function
373      * <code>
374      *     function ( \yii2cdn\Cdn $cdn ) {
375      *         // some logic here
376      *     }
377      * </code>
378      * @param string $property (optional) Default component property name (default: cdn)
379      * @return Cdn
380      * @throws \yii\base\InvalidConfigException When the callback parameter is not a function
381      */
382     public function whenOnline ( $callback, $property = 'cdn' ) {
383 
384         if ( !is_callable($callback) ) {
385             throw new InvalidParamException ("Parameter '{callback}' should be a function");
386         }
387 
388         if ( self::isOnline()  ) {
389             call_user_func_array( $callback, [\Yii::$app->get($property)] );
390         }
391 
392         return $this;
393     }
394 }
395 
API documentation generated by ApiGen