Store
Community Documentation

v3 Knowledgebase

Libraries and phpFox

Recently, I have participated in a forum discussion about libraries and how to implement them in phpFox. Within this discussion, I promised Data66 that I would write a knowledge base article about integrating libraries. I hope that this presentation does more to clear up the process than to confuse the reader. I would also like to thank the other members of the discussion, especially Steward, for their insights, without which I would be unable to write this with anything but a basic understanding of the subject.

In phpFox, libraries are stored within the include/library folder. Those libraries that are specific to phpFox are stored in the include/library/phpfox/ folder. How you implement a library depends on how you wish to initialize it. If you would like to call it from phpFox using phpFox conventions you could put the library folder inside the include/library/phpfox folder and you can call it using conventional fox methods.

For example, if I create a library folder called 'web' and place a file within the 'include/library/web/' path called 'web.class.php', then I could call a web library function with
PHP:
Phpfox::getLib('web')->foo() 
. The interface is already there to implement the new library. This makes sense in that it would be nice for the fox developers to be able to quickly implement library changes as they update their product. There are some things to deal with in using the phpFox interface. The structure of the library must resemble fox's library(one folder deep, extension '.class.php', that kind of stuff). Also some people like to implement code in a certain way and would rather not use fox conventions.

You can put the library in the include/library folder with some additional coding on your part. In the forum thread, the example that I cited was implementing a library to allow you to download the contents of an array as an excel worksheet. In this example, I downloaded the open source library file from http://code.google.com/p/php-excel/downloads/detail?name=php-excel-v1.1-20090910.zip . After unzipping I place the phpexcel folder in the include/library folder. Then I wrote a plugin "init.php" to access the init hook in the include/init.inc.php file. This is one of the first files that run when you use phpFox and is where other vital classes are defined. In this case I placed code to create a global class based upon the phpexcel library. It looked like this:

PHP:
require(PHPFOX_DIR_LIB 'phpexcel' PHPFOX_DS 'php-excel.class.php'); 


after this step, the phpexcel library is now part of phpfox and can be called from any component or service you wish to create.
In order to test this, I made a module called 'test' and put an index file controller and template in it. I also added a plugin directory where the init.php file was placed. Then, in the module/test/include/component/controller/index.class.php file I added this code:
PHP:
/**
 * [PHPFOX_HEADER]
 */

defined('PHPFOX') or exit('NO DICE!');

/**
 * 
 * 
 * @copyright        
 * @author          webwolf
 * @package          
 * @version         
 */

class Test_Component_Controller_Index extends Phpfox_Component 

    public function 
process() 
    {         

$data Phpfox::getLib('database')->select('user_id, full_name, email')
    ->
from(Phpfox::getT('user'))
    ->
limit(3)
    ->
execute('getSlaveRows');

// generate file (constructor parameters are optional)
$xls = new Excel_XML('UTF-8'false'My Test Sheet');
$xls->addArray($data);
$xls->generateXML('my-test');

    }


When I pointed to test I got a download prompt with the excel file ready to download. (It contained three fields from the first three users).

This was a fun exercise and it seemed to work okay, but as Steward pointed out, you don't necessarily want to place a large block of code in play that is rarely needed. His suggestion was to load a loader class, rather than the actual library, that you could use some standard method of invoking. He also suggested a library folder that would be standard on all servers that you deal with, so after installing a library on one server you could use similar code to call the library on other servers, regardless of the program from which you are calling.

Taking all of this into account, I decided to try one more implementation method. I created a folder in include/library path called 'webwolf'. This folder will hold the phpexcel library folder as well as any other library that I wish to include in the future. I changed the 'init' plugin call to be:
PHP:
final class webwolf
{
    public static function 
loadLib($sFolder,$sFile)
    {
        if(
file_exists (PHPFOX_DIR_LIB.'webwolf'.PHPFOX_DS.$sFolder.PHPFOX_DS.$sFile.'.class.php'))
        {
            require_once(
PHPFOX_DIR_LIB.'webwolf'.PHPFOX_DS.$sFolder.PHPFOX_DS.$sFile.'.class.php'); 
            return 
true;
        }
        else
        {
            return 
false;
        }
    }


The purpose of this code is to provide a standard way to access the library(s) within phpFox. This will not load the library upon running fox but only if you call for the library within your own code. For those unfamiliar with fox constants, those that you see in the above code are defined in the include/setting/common.sett.php and constant.sett.php files. I also provided separate folder and file parameters because the particular library that I choose as an example had different names for the folder and file. To prevent that from being a problem in any future libraries that I include, I went this way.

Now, the code to call the library. I used the same test module as above to test this library installation. The index.class.php code now looks like this:
PHP:
/**
 * [PHPFOX_HEADER]
 */

defined('PHPFOX') or exit('NO DICE!');

/**
 * 
 * 
 * @copyright        
 * @author          webwolf
 * @package          
 * @version         
 */

class Test_Component_Controller_Index extends Phpfox_Component 

    public function 
process() 
    {         
    
//Call the loader program function for the target library
    
$bTest webwolf::loadLib('phpexcel','php-excel');
    
//Load 30 records from phpfox_user table
    
$data Phpfox::getLib('database')->select('*')
        ->
from(Phpfox::getT('user'))
        ->
limit(30)
        ->
execute('getSlaveRows');
    
//process the array to extract the keys and add as the first record
    
$data2 = array();
    foreach(
$data[0] as $key => $value)
    {
        
$sTmp=str_replace("_"," ",$key);
        
$sTmp=ucwords ($sTmp);
        
$data2[$key]=$sTmp;
    }

    
array_unshift($data$data2);

    
// generate file (constructor parameters are optional)
    //make sure the loadLib succeeded before we use the object 
    //else send to 'not found' page
    
if($bTest)
    {
        
$xls = new Excel_XML('UTF-8'true'My Test Sheet');
        
$xls->addArray($data);
        
$xls->generateXML('my-test');
    }
    else
    {
        return 
Phpfox::getLib('module')->setController('error.404');
    }
    }


The first thing to do is to call the library. I did this with:
PHP:
$bTest webwolf::loadLib('phpexcel','php-excel'
If the library is successfully invoked, the $bTest will come back as true. Then you can run the class functions based upon testing this variable.
I also updated this code a little so that the table column names will show as the header in the worksheet. If the library is not found, it will show as a not found error (There are probably better ways to do this).

If you want to include a library file with a product that you may be developing, I don't know of a good way to do this other than export the product and then insert the library files into the zipped file inside the appropriately named folders. The calling code will already be in the module you are providing, so the files and folders are all that should be required.

I hope this is of some help to those trying to understand some of the ways Fox does library code and how you can make it work for your project.

web