Yii Framework Forum: Including An External Folder With Subfolders And Libraries - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Including An External Folder With Subfolders And Libraries Rate Topic: -----

#1 User is offline   klammeraffe 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 30
  • Joined: 07-September 12
  • Location:Berlin, Germany

Posted 28 December 2012 - 02:21 PM

I want to use Elastica, a PHP client of ElasticSearch - a search engine somewhat similar to solr.

Now the installation guide of Elastica says to use autoload. But as far as I got it, the autoload features of yii work a little different. I anyway tried and created a symbolic link of the main folder Elastica in components and added to my main.php the line
			'import'=>array(
				'application.components.Elastica.*',

Now the guide says I can instantiate Elastica with $elasticaClient = new Elastica_Client(); which would call components/Elastica/Client.php because they included this nasty str_replace-feature in their autoload approach:
str_replace('_', '/', $class);
Well, Yii is obviously looking for Elastica_Client.php instead.

How would I do it right in a yii-way in order to be able to instantiate as mentioned and not touching the Elastica code or file structure?
0

#2 User is offline   Backslider 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 363
  • Joined: 23-July 09

Posted 28 December 2012 - 08:01 PM

The class filename should be exactly the same as the class name. That's the Yii way. I think some renaming should fix your problem.
We were all once expert at....... nothing.

yii-language-behavior

My Blog
0

#3 User is offline   klammeraffe 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 30
  • Joined: 07-September 12
  • Location:Berlin, Germany

Posted 29 December 2012 - 06:21 AM

I will do that for now.

But since ElasticSearch as well as Elastica are in a fast development cycle and I would like to be able to simply pull the updates from GitHub - without renaming the 89 files each time - it doens't seem to be the ideal solution.

Any other idea for the future?
0

#4 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 2,601
  • Joined: 10-October 10
  • Location:Denmark

Posted 29 December 2012 - 06:44 AM

You could write your own autoloader extension.

Take a look at EZendAutoloader extension - here's a sample of how to register a custom autoloader with Yii (in index.php):



$app = Yii::createApplication('WebApplication', $config);

Yii::import('ext.EZendAutoloader', true);

EZendAutoloader::$prefixes = array('Zend');
EZendAutoloader::$basePath = Yii::getPathOfAlias('common.lib') . DIRECTORY_SEPARATOR;

Yii::registerAutoloader(array("EZendAutoloader", "loadClass"), true);

$app->run();

"Less noise - more signal"
0

#5 User is offline   klammeraffe 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 30
  • Joined: 07-September 12
  • Location:Berlin, Germany

Posted 29 December 2012 - 06:58 AM

Thank you for your solution. To write my own autoloader extension is probably beyond my current level of knowledge of Yii as well as PHP but I will certainly keep it in mind for later.
0

#6 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 2,601
  • Joined: 10-October 10
  • Location:Denmark

Posted 29 December 2012 - 07:51 AM

I didn't say that you should write your own from scratch. :)

Take a look at the Zend Autoloader Yii extension, and modify it.
Am I mistaken in assuming that the only thing you need to change to make it work is the word 'Zend' ?
"Less noise - more signal"
0

#7 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 668
  • Joined: 12-September 10
  • Location:Austria

Posted 29 December 2012 - 08:28 AM

Maybe something like this. It's only an idea, not tested (don't know anything about Elastica).

1. Create Application component 'ElasticaLoader.php' in protected/components folder.


class ElasticaLoader extends CApplicationComponent
{
    public $libPath;

    //see: http://elastica.io/en#section-include
    public function __autoload_elastica ($class)
    {
        $path = str_replace('_', '/', $class);

        if (file_exists($this->libPath . $path . '.php')) {
            require_once($this->libPath . $path . '.php');
        }
    }


    public function init()
    {
       Yii::registerAutoloader(array($this,'__autoload_elastica'),true);
    }
}




2. Preload the component in config/main.php


    ...
 
    'preload'=>array('log','importelastica'),

    ...

     'components'=>array(
        
      ...

        'importelastica'=>array( 
            'class' => 'application.components.ElasticaLoader',
            'libPath' => '/var/www/', //assume you installed Elastica to /var/www/Elastica
        ),

     ...



If you don't need to 'preload' in the application, remove importelastica from 'preload' and call 'Yii::app()->getComponent('importelastica');' in a controllers/modules init() or actionX method.
2

#8 User is offline   klammeraffe 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 30
  • Joined: 07-September 12
  • Location:Berlin, Germany

Posted 29 December 2012 - 10:04 AM

I am just starting, but it works splendid so far. All libraries seem to get loaded as wanted. Thanks a lot!
0

#9 User is offline   seenivasan 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 620
  • Joined: 17-June 12
  • Location:Chennai,TamilNadu,India.

Posted 29 December 2012 - 11:32 AM

Dear Friend

The solution provided by joblo is indeed very elegant.

The question arises where to put that particular method for Yii::registerAutoloader.

Following is one approach.

I put the Elastica folder inside components folder.

Then I added the following.

protected/components/controller.php
class Controller extends CController
{
........................................................
public function autoloadElastica ($class)
    {
        $path = str_replace('_', '/', $class);

        if (file_exists(Yii::getPathOfAlias('application.components')."/". $path . '.php')) 
        {
            require_once(Yii::getPathOfAlias('application.components')."/". $path . '.php');
        }
    }

    public function init()
    {
       Yii::registerAutoloader(array($this,'autoloadElastica'),true);
    }
..............................................................


Regards.
0

#10 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 2,601
  • Joined: 10-October 10
  • Location:Denmark

Posted 29 December 2012 - 12:13 PM

For the record, the Zend Autoloader extension looks like this:


<?php
/**
 * EZendAutoloader
 *
 * @author Alexander Makarov
 * @version 1.1
 *
 * See readme for instructions.
 */
class EZendAutoloader {
	/**
     * @var array class prefixes
     */
	static $prefixes = array(
		'Zend'
	);

	/**
     * @var string path to where Zend classes root is located
     */
    static $basePath = null;

    /**
 	* Class autoload loader.
 	*
 	* @static
 	* @param string $class
 	* @return boolean
 	*/
    static function loadClass($className){
		foreach(self::$prefixes as $prefix){
			if(strpos($className, $prefix.'_')!==false){
				if(!self::$basePath) self::$basePath = Yii::getPathOfAlias("application.vendors").'/';
				include self::$basePath.str_replace('_','/',$className).'.php';
				return class_exists($className, false) || interface_exists($className, false);
			}
		}
		return false;
    }
}


Pretty much the same as Joblo's solution. :)

Written by Samdark, from https://github.com/y...oader-component
"Less noise - more signal"
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users