I want to use the HTMLpurifier in combination with the Zend Framework. I would love to load the Class and its files with the Zend_Loader. How would you include it? Would you just use the HTMLPurifier.auto.php or do you know a better way of doing it?
I use HTML Purifier as a filter in my Zend Framework project. Here's an altered version of my class:
require_once 'HTMLPurifier.includes.php';
require_once 'HTMLPurifier.autoload.php';
class My_Filter_HtmlPurifier implements Zend_Filter_Interface
{
protected $_htmlPurifier = null;
public function __construct($options = null)
{
// set up configuration
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.DefinitionID', 'My Filter');
$config->set('HTML.DefinitionRev', 1); // increment when configuration changes
// $config->set('Cache.DefinitionImpl', null); // comment out after finalizing the config
// Doctype
$config->set('HTML.Doctype', 'XHTML 1.0 Transitional');
// configure caching
$cachePath = APPLICATION_PATH . '/../cache/htmlpurifier';
if (!is_dir($cachePath)) {
mkdir($cachePath, 0755, true);
}
$cachePath = realpath($cachePath);
$config->set('Cache.SerializerPath', $cachePath);
if (!is_null($options)) {
//$config = HTMLPurifier_Config::createDefault();
foreach ($options as $option) {
$config->set($option[0], $option[1], $option[2]);
}
}
$this->_htmlPurifier = new HTMLPurifier($config);
}
public function filter($value)
{
return $this->_htmlPurifier->purify($value);
}
}
Unless I'm misunderstanding the question (Or HTMLpurifier). If you have Zend_Loader running and it's set to autoload.
require_once('Zend/Loader.php');
Zend_Loader::registerAutoload();
Or something to that effect. Put the HTMLpurifier class in your library directory. I'm just not sure on it's actual class name.
You can just put the class file in the library directory and call it by it's name, or maybe toss it in a misc package.
Examples
// SITE/library/Zend/Auth.php
class Zend_Auth
{
}
// SITE/library/htmlpurifier.php
class htmlpurifier
{
}
// SITE/library/misc/htmlpurifier.php
class Misc_HTMLpurifier
{
}
Make sense?
you can register an autoloader class using the Zend_Loader class. when you call the registerAutoLoad() method without any parameters, you are actually registering Zend_Loader itself as an autoloader. so:
Zend_Loader::registerAutoLoad();
// equals to: Zend_Loader::registerAutoLoad('Zend_Loader'),true);
Zend_Loader tries to load classes using Zend Framework's naming convention, which is like this:
each class is defined in a separate file
each class name begins with a capitalized letter
underlines in class name, means a directory level.
so if 'Zend_Loader' is the name of a class, it is defined in the file 'Loader.php' in 'Zend' directory in your path. to you PHP can file load this class from file Zend/Loader.php
if your classes follow this naming convention, they can be automatically loaded using the same autoloader. else, you need to define your own autoloader. write an autoloader class winch can extend Zend_Loader, and define the loading functionality so that it will load classes with other naming conventions. then register your own autoloader with Zend_Loader. like this:
Zend_Loader::registerAutoLoad('myLoader',true);
I've put the contents of library of the archive of HTMLPurifier in my library path. So I have this directory structure :
library/
HTMLPurifier\
HTMLPurifier.auto.php
...
HTMLPurifier.safe-includes.php
And then I put this on top of the file where I'm using the HTMLPurifier :
require_once 'HTMLPurifier.safe-includes.php';
Ugly, but it's working.
Related
Trying to get my feet wet on ZF2 and I've stumbled on my first problem. Say on a module I want to use Shanty_Mongo (an external library to connect to MongoDb)
So I've copied the entire Shanty directory on the library and created a new Model class:
namespace Dummy\Model;
use Shanty\Mongo\Document;
class Dummy extends Shanty_Mongo_Document {
public function setConnections( $connections ) {
Shanty_Mongo::addConnections($connections);
}
}
(The setConnections() is to be used by DI, if I've understood it well)
This seems to fail to find Shanty_Mongo_Document. Should I add something to the application.config.php to point to the extra library?
The library Shanty_Mongo is an "old" underscore separated library without using namespaces. In ZF2, the style is the same PSR-0 standard but with namespaces (so Shanty_Mongo will be Shanty\Mongo). However, you are able to load these old style fine with a classmap for example. Then you can use underscore separated classes inside your ZF2 project.
I'd suggest you create a module for this library and put that module under ./vendor (for "modules providing 3rd party features"). In this module, you can create the following directory structure (I assume the name of the module is ShantyMongo):
./vendor/ShantyMongo/
library/
Module.php
autoload_classmap.php
autoload_function.php
autoload_register.php
The library is a submodule to the Shanty-Mongo git repository. The file autoload_classmap.php is a classmap created by the php script classmap_generator.php inside the bin directory of the ZF2 repository. Then the autoload_function.php can be something simple as this:
<?php
return function ($class) {
static $map;
if (!$map) {
$map = include __DIR__ . '/autoload_classmap.php';
}
if (!isset($map[$class])) {
return false;
}
return include $map[$class];
};
And autoload_register.php something like this:
<?php
spl_autoload_register(include __DIR__ . '/autoload_function.php');
To let the ZF2 application know you have this module, you need to fill the module.php with a ShantyMongo\Module class. Something like this should be sufficient:
<?php
namespace ShantyMongo;
use Zend\Module\Consumer\AutoloaderProvider;
class Module implements AutoloaderProvider
{
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
)
);
}
}
If you add "ShantyMongo" to your modules array in application.config.php you now have set up the autoloader for this 3rd party library inside ZF2. You can then use your model as follows:
<?php
namespace Dummy\Model;
class Dummy extends Shanty_Mongo_Document {
public function setConnections ($connections) {
Shanty_Mongo::addConnections($connections);
}
}
Because ShantyMongo doesn't use namespaces, you don't have that use statement anymore.
I am using a custom scheme in naming my files. Any pointers on how to autoload them with Zend's autoloader?
Thanks!
You can write your own autoloader class and register it with the ZF autoloader. There is a brief bit about this in the manual: http://framework.zend.com/manual/en/zend.loader.autoloader.html#zend.loader.autoloader.interface
Basically it's just a class defining one method which takes the class name as the parameter. So for you it would be something like:
class My_Autoloader implements Zend_Loader_Autoloader_Interface
{
public function autoload($class)
{
$filename = $class.'.obj.php';
require $filename;
}
}
the above assumes the classes are on the include path, if not, just stick the full path in front of $filename. Add any other mapping/checking you need in here and then register it as per the example in the manual. Normally you would do this in your bootstrap.
I'm trying to implement custom exception classes for a zend project.
I use modules and all my classes are under library.
so a filename DuplicateFileException.php which is under
APPLICATION_PATH "/../library/Abra/Exception" contains
class Abra_Exception_FileNotFoundExcpetion extends Exception {}
class Abra_Exception_MissingFileException extends Exception {}
class Abra_Exception_DuplicateFileException extends Exception {}
class Abra_Exception_FileIOException extends Exception {}
so the ErrorController works fine when i only throw Abra_Exception_DuplicateFileException
because there is indeed a file called DuplicateFileException, but the app breaks when i throw any other than that Exception.
I just can't believe that i have to create a file for each of them.
so how to work around it?
thanks for reading.
Proper zend-way would be implementing your own autoloader class. IT will implement autoload method. You can then use Zend_Autoloader autoloader stack to oad your classes. You just need to have some kind of system/logic in your classname->filename mapping.
class Abra_Autoloader
{
public function autoload($className)
{
if (strpos('Abra_Exception', $className) !== false) {
include $someFile; //faster
}
}
}
//anywhere in bootstrap (preferably in some autoloading section of yours)
// autoloader will load only classes starting with "abra"
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);
$autoloader->pushAutoloader(array('Abra_Autoloader ', 'autoload'), 'Abra');
Please note that at least teh autoloader class should be Zend_Loader-loadable :)
The Zend autoloader works by mapping requested class names to filesystem paths so you can't make it load a file for a class where the filename does not match.
If you really want to persist down this path, I'd just include the file in your Bootstrap class, eg
protected function _initRequires()
{
require_once 'Abra/Exception/DuplicateFileException.php';
// assuming your "library" folder is on the include path
}
what is the best practice for adding and accessing libraries to ZF? I'm trying to add phpmailer, should I just add it to the library folder? How can I access this file now, as it does not use the ZF naming conventions. Thanks!
Drop the relevant files into the library folder. Then you could create an autoloader something like this:
In the file library/My/Loader/Autoloader/PhpMailer.php:
class My_Loader_Autoloader_PhpMailer implements Zend_Loader_Autoloader_Interface
{
/**
* Autoload a class
*
* #param string $class
* #return mixed
* False [if unable to load $class]
* $class [if $class is successfully loaded]
*/
public function autoload($class)
{
if ('PHPMailer' === $class) {
include 'class.phpmailer.php';
return $class;
}
return false;
}
}
Then add this autoloader to the ZF autoloader stack, probably in Bootstrap:
protected function _initAutoloader()
{
$autoloader = Zend_Loader_Autoloader::getInstance();
// The following is not necessary if My_ is already a registered namespace
// in the ZF autoloader
require 'My/Loader/Autoloader/PhpMailer.php';
$autoloader->pushAutoloader(new My_Loader_Autoloader_PhpMailer());
}
I've done something like this for examples with more involved legacy class naming/mapping and it's been quite helpful.
The simple solution is to drop the PHPMailer class (and any other files) into your library folder.
As PHPMailer seems to use a filename convention that won't apply well to the autoloader (class.phpmailer.php), I'd just require the class file in your Bootstrap
You should then be able to create a new PHPMailer class anywhere in your app.
You could try and register an autoloader that would map the class name PHPMailer to class.phpmailer.php however IMO it's not worth the effort.
UPDATE
Come to think of it, I'd ignore the Bootstrap part and simply require the class when it's needed (say, in your controller). As the file is in your include path, all you would need is
require_once 'class.phpmailer.php';
$mailer = new PHPMailer;
I have a folder in my library folder which is named after my website. The folder path is like:
~\www\library\myWebsite.com
If I'm using Zend autoloader to load the namespace of everything in the library path, will I have any trouble autoloading a class from that file with a namespace like this:
\myWebsite.com\myClass::myFunction();
I have looked online for documentation on this and I can't find any info about using periods in this way.
I tried it and the complication is in PHP. I think Zend is registering the namespace fine, because when I call \Zend_Load_Autoloader::getRegisteredNamespaces() it shows that it's registered. but when I call the static method from the fully qualified namespace, php gives an error of this:
Fatal error: Undefined constant 'myWebsite' in /home/jesse/www/application/controllers/MyController.php on line 15
It seems like PHP is terminating the namespace identifier, during parsing, at the . (period character). This is dissapointing because to me having a library named after the website was important to my design.
I will rename the directory to myWebsitecom or possibly make the .com it's own sub directory like
myWebsite\com and incorporate that into my namespace tree like: \MyNamespace\Com\MyClass::myFunction();
The easiest way to find out is to try it.
If it doesn't work, you could always write a custom autoloader to make it work. I don't have much experience with php namespaces, but the autoloader would look something like this (I imagine you'll have to tinker with it a bit to determine the correct file path given the class name):
<?php
class My_Loader_Autoloader_MyWebsite implements Zend_Loader_Autoloader_Interface {
/**
* (non-PHPdoc)
* #see Zend_Loader_Autoloader_Interface::autoload()
*/
public function autoload($class) {
if (strtolower(substr($class, 0, 9)) == 'mywebsite') {
$file = realpath(APPLICATION_PATH . '/../library/myWebsite.com/' . $class);
if ($file) {
require_once $file;
return $class;
}
}
return false;
}
}
then put this in your bootstrap:
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->pushAutoloader(new My_Loader_Autoloader_MyWebsite());
and if this class must be in that myWebsite.com directory, you could just cheat and throw in a require in there too:
require_once(APPLICATION_PATH . '/../library/myWebsite.com/Loader/Autoloader/MyWebsite.php');