<?php
/**
 * This file is part of the CarteBlanche PHP framework.
 *
 * (c) Pierre Cassat <me@e-piwi.fr> and contributors
 *
 * License Apache-2.0 <http://github.com/php-carteblanche/carteblanche/blob/master/LICENSE>
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CarteBlanche\Controller;

use \CarteBlanche\CarteBlanche;
use \CarteBlanche\Abstracts\AbstractController;
use \CarteBlanche\Library\Form\Field;
use \CarteBlanche\Library\Helper;
use \CarteBlanche\Exception\NotFoundException;
use \CarteBlanche\Exception\AccessForbiddenException;
use \CarteBlanche\Exception\InternalServerErrorException;
use \CarteBlanche\Exception\Exception;
use \CarteBlanche\Exception\ErrorException;
use \CarteBlanche\Exception\DomainException;
use \CarteBlanche\Exception\RuntimeException;
use \CarteBlanche\Exception\InvalidArgumentException;
use \CarteBlanche\Exception\UnexpectedValueException;

/**
 * Default dvelopment controller extending abstract \CarteBlanche\Abstracts\AbstractController class
 *
 * @author  Piero Wbmstr <me@e-piwi.fr>
 */
class Dev extends AbstractController
{

    /**
     * The directory where to search the views files
     */
    static $views_dir = 'dev/';

    /**
     * The home page of the controller
     */
    public function indexAction()
    {
        $ctt = '';

        $this->render(array(
            'output'=> $ctt
        ));
    }

    /**
     * Special page to clear user data (such as session)
     */
    public function clearAction()
    {
        $this->getContainer()->get('session')->clear();
        $this->getContainer()->get('router')->redirect( $this->getContainer()->get('router')->buildUrl() );
    }

// -------------------
// Special method for application full map
// -------------------

    /**
     * Page of application map
     *
     * @return string The view content
     */
    public function app_mapAction()
    {
        $root_path = CarteBlanche::getPath('root_path');
        $base_path = $root_path;
        $bundles_base_path = $root_path
            .CarteBlanche::getPath('bundles_dir');
        $controller_dirname = 'Controller';

        $app_controllers = $bundles_controllers = array();
    /*
        $classMap = require __DIR__ . '/autoload_classmap.php';
        if ($classMap) {
            $loader->addClassMap($classMap);
        }
    */
        // the global app dir
        $_dir = new \CarteBlanche\Model\DirectoryModel;
        $_dir->setPath(CarteBlanche::getPath('carte_blanche_core'));
        $_dir->setDirname( $controller_dirname );
        $_app_ctrls = $_dir->scanDir();
        if ($_app_ctrls) {
            foreach ($_app_ctrls as $_ctrl) {
                $controller = new \stdClass;
                $controller->short_name = str_replace('.php', '', $_ctrl);
                $controller->name = \CarteBlanche\App\Locator::locateController($controller->short_name);
                $controller->path = $base_path.$controller_dirname.'/'.$_ctrl;
                $controller->methods = array();
                if (\CarteBlanche\App\Loader::classExists($controller->name)) {
                    $_cls = new \ReflectionClass( $controller->name );
                    foreach ($_cls->getMethods(\ReflectionMethod::IS_PUBLIC) as $_meth) {
                        if (strstr($_meth->name, 'Action')) {
                            $method = new \stdClass;
                            $method->name = $_meth->name;
                            $method->short_name = str_replace('Action', '', $_meth->name);
                            $method->expect_arguments = false;
                            foreach ($_meth->getParameters() as $_param) {
                                if (!$_param->isOptional()) {
                                    $method->expect_arguments = true;
                                    continue;
                                }
                            }
                            $controller->methods[] = $method;
                        }
                    }
                }
                $app_controllers[] = $controller;
            }
        }

        // the bundles dirs
        $known_bundles = $this->getContainer()->get('bundles');
        if (is_null($known_bundles)) $known_bundles = array();
        $known_bundles_lower = $known_bundles;
        foreach ($known_bundles_lower as $key=>$k) {
            $known_bundles_lower[strtolower($key)] = $k;
        }
        $_dir->setPath(dirname($bundles_base_path));
        $_dir->setDirname(basename($bundles_base_path));
        $_bundles = $_dir->scanDir();
        if ($_bundles) {
            $_bundle_dir = new \CarteBlanche\Model\DirectoryModel;
            $_bundle_dir->setPath( $bundles_base_path );
            foreach ($_bundles as $_bundle) {
                if (!array_key_exists($_bundle, $known_bundles) && !array_key_exists($_bundle, $known_bundles_lower)) {
                    foreach ($known_bundles as $nm=>$bdl) {
                        if ($bdl->getShortname()==$_bundle) {
                            $_bundle = $nm;
                        }
                    }
                    if (!array_key_exists($_bundle, $known_bundles) && !array_key_exists($_bundle, $known_bundles_lower)) {
                        continue;
                    }
                }
                if (array_key_exists($_bundle, $known_bundles)) {
                    $this_bundle_path = $known_bundles[$_bundle]->getDirectory()
                        .'/'.$known_bundles[$_bundle]->getNamespace();
                }
                if (array_key_exists($_bundle, $known_bundles_lower)) {
                    $this_bundle_path = $known_bundles_lower[$_bundle]->getDirectory()
                        .'/'.$known_bundles_lower[$_bundle]->getNamespace();
                }
                $bundles_controllers[$_bundle] = array();
                $_bundle_dir->setDirname( str_replace($_bundle_dir->getPath(), '', $this_bundle_path.'/'.$controller_dirname) );
                $_bundles_ctrls = $_bundle_dir->scanDir();

                if ($_bundles_ctrls)
                foreach ($_bundles_ctrls as $_ctrl) {
                    $controller = new \stdClass;
                    $controller->short_name = str_replace('.php', '', $_ctrl);
                    $controller->name = '\\'.$_bundle.'\\Controller\\'.$controller->short_name;
                    $controller->path = $bundles_base_path.$_bundle.'/'.$controller_dirname.'/'.$_ctrl;
                    $controller->methods = array();
                    if (\CarteBlanche\App\Loader::classExists($controller->name)) {
                        $_cls = new \ReflectionClass( $controller->name );
                        if ($_cls->isAbstract()) {
                            continue;
                        }
                        foreach ($_cls->getMethods(\ReflectionMethod::IS_PUBLIC) as $_meth) {
                            if (strstr($_meth->name, 'Action')) {
                                $method = new \stdClass;
                                $method->name = $_meth->name;
                                $method->short_name = str_replace('Action', '', $_meth->name);
                                $method->expect_arguments = false;
                                foreach ($_meth->getParameters() as $_param) {
                                    if (!$_param->isOptional()) {
                                        $method->expect_arguments = true;
                                        break;
                                    }
                                }
                                $controller->methods[] = $method;
                            }
                        }
                    }
                    $bundles_controllers[$_bundle][] = $controller;
                }
            }
        }

        $mode_data = \CarteBlanche\CarteBlanche::getKernelMode(true);
        return array(self::$views_dir.'app_map', array(
            'title' => $this->trans('Application full map'),
            'debug' => isset($mode_data['debug']) ? $mode_data['debug'] : false,
            'app_controllers'=>$app_controllers,
            'bundles_controllers' => $bundles_controllers,
        ));
    }

    /**
     * Page of application configuration
     *
     * @return string The view content
     */
    public function cb_configAction()
    {
        $config = $this->getContainer()->get('config')->dump();
        $reflection_cb = new \ReflectionClass('\CarteBlanche\App\Kernel');
        $constants = $reflection_cb->getConstants();

        $mode_data = \CarteBlanche\CarteBlanche::getKernelMode(true);
        return array(self::$views_dir.'app_config', array(
            'title' => $this->trans('Application full config'),
            'debug' => isset($mode_data['debug']) ? $mode_data['debug'] : false,
            'constants'=>$constants,
            'config' => $config,
        ));
    }

    /**
     * Page of application administration (test)
     *
     * @return string The view content
     */
    public function adminAction()
    {
        $fields = $values = array();

/*
TODO

- clear web cache
- clear app cache
- clear i18n cache
- clear generated images
- disable caches
*/

        $fields[] = new Field('clear_web_cache', array(
            'type'=>'submit',
            'action'=>'test',
            'value'=>'ok',
            'label'=>'Clear web cache',
        ));

        $form = new \Tool\Form(array(
            'form_id'=>'app_admin',
            'fields'=>$fields,
            'values'=>$values
        ));

        if ($this->getContainer()->get('request')->isPost()) {
            $_posted = $this->getContainer()->get('request')->getData();

            if (isset($_posted['clear_web_cache']) && $_posted['clear_web_cache']==='ok') {
                $path = \Library\Helper\Directory::slashDirname(CarteBlanche::getPath('cache_path'));
                $ok = \Library\Helper\Directory::purge($_path);
            }

            var_export($_posted);
            exit('yo');
        }

        return array(self::$views_dir.'app_admin', array(
            'title' => 'App admin',
            'form'=>$form,
        ));
    }

// -------------------
// Special method for tests
// -------------------

    /**
     * Page of test
     *
     * @param mixed $arg1 Test arg 1
     * @param mixed $arg2 Test arg 2
     * @return string The view content
     */
    public function testAction($arg1 = null, $arg2 = 'value')
    {
//                throw new InternalServerErrorException("Capture l'exception par défaut", 12);
                throw new NotFoundException("Capture l'exception par défaut", 12);

        $lang_sel = new \Tool\LanguageSelector(array(
            'home'=>$this->getContainer()->get('router')->buildUrl(array('controller'=>'cms', 'altdb'=>$_altdb)),
            'current'=>$title,
        ));

        return array('test', array(
            'title' => 'Test page',
            'language_selector' => $lang_sel,
        ));
/*
echo '
';

$session = CarteBlanche::getContainer()->get('session');

//$session->set('test', array('one', 'two'));
if ($session->has('test')) {
    echo '
test :: '.var_export($session->get('test'),1);
} else {
    echo '
test is empty';
}

//$session->setFlash('test qsdf qsdfqsdf', 'ok');
//$session->setFlash('test qsdf qsdfqsdf', 'error');
if ($session->hasFlash()) {
    echo '
flashes :: '.var_export($session->allFlashes(),1);
} else {
    echo '
flashes are empty';
}

echo '

'.var_export($session,1);
echo '

'.var_export($_SESSION,1);
echo '
';
exit('yo');
*/
        CarteBlanche::log('test');

        $ctt='';
        $ctt .= '
Premier argument reçu: '.var_export($arg1,1);
        $ctt .= '
Second argument reçu: '.var_export($arg2,1);
        $ctt .= '
Tous les arguments reçus: '.var_export(func_get_args(),1);

/*
     $to      = 'me@e-piwi.fr';
     $subject = 'le sujet';
     $message = 'Bonjour !';
     $headers = 'From: webmaster@example.com' . "\r\n" .
     'Reply-To: webmaster@example.com' . "\r\n" .
     'X-Mailer: PHP/' . phpversion();
     $ok = mail($to, $subject, $message, $headers);
     var_export($ok);

exit('yo');

        // test envoi de mail
        $txt_message_iso = "Hello dude !\n\nMy line 1 with special chars : é à\nLine 2\nLine 3";
        $html_message_iso = "Hello dude !\n\n

My line 1 with special chars : é à	Line 2	Line 3

";

$html_lorem_ipsum = <<<EOT
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

Lorem Ipsum "Dummy Text" Gets Spam Filtered

Was working on a quick HTML Email trick to post here on the blog, and while I was sending myself test emails, I noticed they were getting thrown into my junk folder. I tweaked my HTML a little (it was admittedly a little sloppy) but it didn't help. Everytime I sent my test messages, Mozilla Thunderbird's built-in spam filter threw every single one into the junk folder. After half a dozen more tests, I finally figured it out. I was using a paragraph of "Lorem Ipsum" placeholder text in my mockup. Once I switched it out with "real" copy (I pulled the first paragraph from the MailChimp home page) it got past the spam filter. So if you're a designer sending yourself some HTML email tests, find some "real" copy to use. Spam filters (Thunderbird's, at least) don't like lorem ipsum. Et tu, Mozilla?

Here's what the email that was getting blocked looked like

And here's the one that got past the spam filter

January 16, 2006 in Tips, Tricks, Best Practices  | Permalink

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d8341d5a5053ef00d834a260d469e2

Listed below are links to weblogs that reference Lorem Ipsum "Dummy Text" Gets Spam Filtered:

Comments

Probably that's because Thunderbird uses a filtering method called "Bayesian" filtering.  Without going into the details of it, the filter checks the words in your message against the words in your inbox.  If there are many in common, it is not junk and if there are few in common, it is.  Thus, since you never receive emails with the words "lorem", "ipsum", or "dolor" in them, the message was marked as spam.  Any mail client that uses this method of filtering will likely have similar problems for similar reasons.

Posted by: Alan Underwood | Jan 19, 2006 5:09:24 PM

The comments to this entry are closed.

EOT;

$mailchimp = new \MimeEmail\Lib\EmailTemplate\MailChimpEmailMarkupLayout();

$mailchimp
	->setVariables(array(
		'MC:SUBJECT'=>'Mail de test',
	))
	->parse();

		$file = _ROOTPATH.'CHANGELOG.md';
//		$mail = new \MimeEmail\Lib\MimeEmail('Piero', 'me@e-piwi.fr', 'pierre.cassat@gmail.com', 'Mail de test', $txt_message_iso);
//		$mail = new \MimeEmail\Lib\MimeEmail('Piero', 'me@e-piwi.fr', null, 'Mail de test', $txt_message_iso);
		$mail = new \MimeEmail\Lib\MimeEmail();

		$mail
			->setTo('me@e-piwi.fr', 'PieroWbmstr')
			->setFrom( 'pierre.cassat@gmail.com', 'Piero' )
//			->setCc( array( 'Piero'=>'pierre.cassat@gmail.com' ) )
//			->setCc( array( 'Piero'=>'pierre.cassat@gmail.com', 'oim'=>'oim@gmail.com' ) )
//			->setCc( array( 'Piero'=>'pierre.cassat@gmail.com', 'oim'=>'oim@gmail.com', 'test@mlkj.com' ) )
//			->setCc( array( 'Piero'=>'pierre.cassat@gmail.com', 'oim'=>'oim@mail.com', 'test@mlkj.com','oiu' ) )
//			->setCc('atelierspierrot@ail.com', 'yo')
//			->setBcc('ateliers.pierrot@gmail.com')

			->setSubject('Mail de test')
			->setText($txt_message_iso)
//			->setHtml($html_lorem_ipsum)
			->setHtml( $mailchimp->getContent() )
			->setText('auto')
			->setAttachment($file)
//			->setDryRun(true)
//			->setSpoolDir( _ROOTPATH.'cache/spool/' )
			;
		$ok = $mail->send(1);
//		$ok = $mail->spool(1);
		echo "
"; var_export($mail); echo "
";
exit('yo');
*/

CarteBlanche::getContainer()->get('i18n')->setLanguage('en');
$date = new \DateTime;

echo '
Tests in english
';

echo _D($date);

_trans('test');

echo '

';
_trans('test_args', array('arg1'=>'AZERTY', 'arg2'=>4.657));

echo '

';
$counter=0;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657));

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657));

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657));

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657));

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657));

echo '
';
echo '
Same tests in french
';

echo _D($date, null, 'UTF-8', 'fr');

_trans('test', array(), 'fr');

echo '

';
_trans('test_args', array('arg1'=>'AZERTY', 'arg2'=>4.657), 'fr');

echo '

';
$counter=0;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657), 'fr');

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657), 'fr');

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657), 'fr');

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657), 'fr');

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657), 'fr');

echo '
';
exit('yo');

echo '
';

$config = new \CarteBlanche\App\Config;

$test_conf_ini = CarteBlanche::getPath('config_path').'tests/test.ini';
$config->load($test_conf_ini, true, 'ini');

$test_conf_json = CarteBlanche::getPath('config_path').'tests/test.json';
$config->load($test_conf_json, true, 'json');

$test_conf_xml = CarteBlanche::getPath('config_path').'tests/test.xml';
$config->load($test_conf_xml, true, 'xml');

$test_conf_php = CarteBlanche::getPath('config_path').'tests/test.php';
$config->load($test_conf_php, true, 'php');

echo "
config->get('scope_1.scope_2.my_bit_value_int'));\n";
var_export($config->get('scope_1.scope_2.my_bit_value_int'));
echo "
config->get('reference_1'));\n";
var_export($config->get('reference_1'));
echo "
config->get('ini.scope_1.my_index'));\n";
var_export($config->get('ini.scope_1.my_index'));
echo "
config->get('ini.reference_1'));\n";
var_export($config->get('ini.reference_1'));
echo "
config->get('reference_2'));\n";
var_export($config->get('reference_2'));
echo "
config->get('abcdef'));\n";
var_export($config->get('abcdef'));
echo "
config->get('abcdef', \CarteBlanche\App\Config::NOT_FOUND_ERROR));\n";
//var_export($config->get('abcdef', \CarteBlanche\App\Config::NOT_FOUND_ERROR));

echo "
config->get('closure_setting', \CarteBlanche\App\Config::NOT_FOUND_ERROR, null, 'php'));\n";
var_export($config->get('closure_setting', \CarteBlanche\App\Config::NOT_FOUND_ERROR, null, 'php'));
echo "
config->get('closure_setting', \CarteBlanche\App\Config::NOT_FOUND_ERROR, null, 'json'));\n";
var_export($config->get('closure_setting', \CarteBlanche\App\Config::NOT_FOUND_ERROR, null, 'json'));
echo "
config->get('closure_setting', \CarteBlanche\App\Config::NOT_FOUND_ERROR, null, 'xml'));\n";
var_export($config->get('closure_setting', \CarteBlanche\App\Config::NOT_FOUND_ERROR, null, 'xml'));
echo "
config->get('closure_setting', \CarteBlanche\App\Config::NOT_FOUND_ERROR, null, 'ini'));\n";
var_export($config->get('closure_setting', \CarteBlanche\App\Config::NOT_FOUND_ERROR, null, 'ini'));

$cb_cfg = \CarteBlanche\App\Locator::locateConfig('carteblanche.ini');
$config->load($cb_cfg);

var_export($config);
echo '
';
exit('yo');

$ok = \CarteBlanche::log(\App\Logger::DEBUG, 'my message');

exit('yo');
echo '
';

echo '
ORIGINAL FILE : '.__DIR__.'/../../../composer.json
';
$file = new \Lib\Manifest\Manifest(__DIR__.'/../../../composer.json');
var_export($file);

echo '
Package from file :
';
$manifest = new \Lib\Manifest\Package($file);
echo '(array access) TITLE => '.$manifest->title.'
';
var_export($manifest);

echo '
Composer from package :
';
$composer = new \Lib\Manifest\Vendor\Composer($manifest);
var_export($composer);

echo '
Node from package :
';
$node = new \Lib\Manifest\Vendor\Node($manifest);
var_export($node);

echo '
Bower from package :
';
$bower = new \Lib\Manifest\Vendor\Bower($manifest);
var_export($bower);

exit('yo');
/*
CarteBlanche::getContainer()->get('i18n')->setLanguage('en');
$date = new \DateTime;

echo '
Tests in english
';

echo _D($date);

_trans('test');

echo '

';
_trans('test_args', array('arg1'=>'AZERTY', 'arg2'=>4.657));

echo '

';
$counter=0;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657));

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657));

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657));

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657));

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657));

echo '
';
echo '
Same tests in french
';

echo _D($date, null, 'UTF-8', 'fr');

_trans('test', array(), 'fr');

echo '

';
_trans('test_args', array('arg1'=>'AZERTY', 'arg2'=>4.657), 'fr');

echo '

';
$counter=0;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657), 'fr');

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657), 'fr');

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657), 'fr');

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657), 'fr');

echo '

';
$counter++;
echo _P(array(
    0=>'test_item_zero',
    1=>'test_item_one',
    2=>'test_item_two',
    3=>'test_item_multi'
), $counter, array('arg1'=>'AZERTY', 'arg2'=>4.657), 'fr');

echo '
';
exit('yo');
*/
/*
		$js_dir = _ROOTPATH._WEBDIR.'js/scripts/';
		$js_files = array(
			_ROOTPATH._WEBDIR.'js/scripts.js',
			$js_dir.'array/array_remove.js',
			$js_dir.'array/join.js',
			$js_dir.'array/dump.js',
		);

		foreach($js_files as $_file)
		{
			getContainer()->get('template_engine')
				->getTemplateObject('JavascriptFile')
				->add( $_file );
		}

		$js_min = $this->getContainer()->get('template_engine')
				->getTemplateObject('JavascriptFile')
				->minify()
				->writeMinified(  );

		$ctt .= '
Minified javascripts : '.htmlentities($js_min).'
';
*/
/*
		$js_minifier = new \App\Minifier;
		$js_minifier
			->setSilent( false )
			->setFilesStack( $js_files )
			->setWebRootPath( __DIR__.'/../../www/' )
			->setDestinationDir( __DIR__.'/../../www/tmp/cache/' )
			->process();

*/

// ASSERTIONS
$a=10;
//assert('$a<0', 'mlkjmlkj'); // only since PHP5.4.8
//assert('$a==0');
//assert('$a<0; // my comment for this assertion');

//throw new \Exception("Capture l'exception par défaut");

trigger_error('qmlskdjfmqlksj', E_USER_WARNING);
trigger_error('qmlskdjfmqlksj2', E_USER_WARNING);
			@fopen(); // error not written
			fopen(); // error

		try{
//			fopen(); // error
			if (2 != 4) // false
				throw new \CarteBlanche\Exception\Exception("Capture l'exception par défaut", 12);
		} catch(\CarteBlanche\Exception\Exception $e) {
			echo $e;
		}

//trigger_error('qmlskdjfmqlksj', E_USER_ERROR);

		trigger_error('Test error string', E_USER_ERROR);

/*
		$my_table = \CarteBlanche\Library\AutoObject\AutoObjectMapper::getAutoObject('article');
		$ctt .= '
Structure de la table "article" :

'.var_export($my_table,1).'
';

		$artid=2;
		$my_article = new \CarteBlanche\Model\BaseModel( 'article', $my_table );
		$my_article->read( $artid );
		$ctt .= "
Contenu de l'article $artid :

".var_export($my_article,1).'
';

		$my_article->getRelations( false );
		$ctt .= "
Contenu de l'article $artid avec relations :

".var_export($my_article,1).'
';
*/

        $this->render(array(
            'output'=> $ctt,
            'title' => 'Test page'
        ));
    }

    /**
     * Page of test for ajax requests
     * @return string The view content
     */
    public function testajaxAction()
    {
        self::$template = 'empty.txt';
        return array('lorem_ipsum', array(
            'title' => 'Test page',
        ));
    }

}

// Endfile


<?php

namespace Potherca\Katwizy;

use Composer\Autoload\ClassLoader;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Dotenv\Dotenv;
use Potherca\Katwizy\Factory\AppKernelFactory;
use Potherca\Katwizy\Factory\ConfigLoaderFactory;
use Potherca\Katwizy\Immutable\Debug;
use Potherca\Katwizy\Immutable\Environment;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\HttpFoundation\Request;

class Bootstrap
{
    ////////////////////////////// CLASS PROPERTIES \\\\\\\\\\\\\\\\\\\\\\\\\\\\
    /** @var bool */
    private $debug;
    /** @var string */
    private $environment;
    /** @var ArgvInput|Request */
    private $input;
    /** @var ClassLoader */
    private $loader;

    //////////////////////////// SETTERS AND GETTERS \\\\\\\\\\\\\\\\\\\\\\\\\\\
    /**
     * @return bool
     */
    private function getDebug()
    {
        if ($this->debug === null) {
            $input = $this->input;

            switch (get_class($input)) {

                case ArgvInput::class:
                    $debug = ((int) getenv('SYMFONY_DEBUG') !== '0') && ($input->hasParameterOption(['--no-debug', '']) === false);
                break;

                case Request::class:
                    $debug = (bool) ((string) new Debug($input));
                break;

                default:
                    $debug = false;
                break;
            }

            $this->debug = $debug;
        }

        return $this->debug;
    }

    /**
     * @return string
     */
    private function getEnvironment()
    {
        if ($this->environment === null) {
            $input = $this->input;

            switch (get_class($input)) {

                case ArgvInput::class:
                    $environment = $input->getParameterOption(['--env', '-e'], getenv('SYMFONY_ENV') ?: Environment::DEVELOPMENT);
                break;

                case Request::class:
                    $environment = (string) new Environment();
                break;

                default:
                    $environment = Environment::PRODUCTION;
                break;
            }

            $this->environment = $environment;
        }

        return $this->environment;
    }

    /** @return ClassLoader */
    private function getLoader()
    {
        return $this->loader;
    }

    /** @return string */
    private function getRootDirectory()
    {
        static $rootDirectory;

        if ($rootDirectory === null) {
            $loader = $this->getLoader();

            $reflector = new \ReflectionObject($loader);

            /* Autoloader at /vendor/composer/ClassLoader.php */
            $rootDirectory = dirname(dirname(dirname($reflector->getFileName())));
        }

        return $rootDirectory;
    }
    //////////////////////////////// PUBLIC API \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    final public static function run(ClassLoader $loader, $input) {

        $bootstrap = new static($loader, $input);

        $bootstrap->load();

        $input = $bootstrap->input;
        $kernel = $bootstrap->createKernel();

        switch (get_class($input)) {

            case ArgvInput::class:
                $bootstrap->handleInput($kernel, $input);
                break;

            case Request::class:
                $bootstrap->handleRequest($kernel, $input);
                break;

            default:
                break;
        }
    }

    /**
     * @param ClassLoader $loader
     * @param ArgvInput|Request $input
     *
     * @throws \InvalidArgumentException
     */
    final public function __construct(ClassLoader $loader, $input)
    {
        $this->loader = $loader;
        if ($input instanceof ArgvInput || $input instanceof Request) {
            $this->input = $input;
        } else {
            throw $this->exception($input);
        }

    }

    /**
     * Loads pre-run requisites
     *
     * @throws \InvalidArgumentException
     */
    private function load()
    {
        $this->loadEnvFile();
        $this->registerAnnotationLoader();
        $this->loadDebug();
    }

    ////////////////////////////// UTILITY METHODS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    /**
     * @return AppKernel
     *
     * @throws \InvalidArgumentException
     * @throws \UnexpectedValueException
     * @throws \RuntimeException
     */
    private function createKernel()
    {
        $debug = $this->getDebug();
        $environment = $this->getEnvironment();
        $rootDirectory = $this->getRootDirectory();

        $configLoaderFactory = new ConfigLoaderFactory($rootDirectory, $environment);
        $configLoader = $configLoaderFactory->create();

        $kernelFactory = new AppKernelFactory($configLoader, $environment, $debug);

        return $kernelFactory->create();
    }

    /**
     * @param mixed $input
     *
     * @return \InvalidArgumentException
     */
    private function exception($input)
    {
        $type = gettype($input);

        if ($type === ' object') {
            $type = get_class($input);
        }

        $exception = new \InvalidArgumentException(
            'Given input must be one of "%s", "%s" given',
            implode('", "', [ArgvInput::class, Request::class]),
            $type
        );

        return $exception;
    }

    private function handleRequest(AppKernel $kernel, Request $input)
    {
        $response = $kernel->handle($input);
        $response = $response->send();
        $kernel->terminate($input, $response);
    }

    private function handleInput(AppKernel $kernel, ArgvInput $input)
    {
        $application = new Application($kernel);

        return $application->run($input);
    }

    private function loadEnvFile()
    {
        $path = $this->getRootDirectory();

        if (is_readable($path . '/.env')) {
            $environmentVariables = new Dotenv($path, '.env');
            $environmentVariables->load();
        }
    }

    private function registerAnnotationLoader()
    {
        AnnotationRegistry::registerLoader([$this->getLoader(), 'loadClass']);
    }

    private function loadDebug()
    {
        if ($this->getDebug()) {
            \Symfony\Component\Debug\Debug::enable();
        }
    }

}

/*EOF*/


<?php

namespace Potherca\Katwizy;

use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Routing\RouteCollectionBuilder;
use Symfony\Component\Yaml\Yaml;

class ConfigLoader
{
    ////////////////////////////// CLASS PROPERTIES \\\\\\\\\\\\\\\\\\\\\\\\\\\\
    /** @var Directories */
    private $directories;
    /** @var string */
    private $environment;

    //////////////////////////// SETTERS AND GETTERS \\\\\\\\\\\\\\\\\\\\\\\\\\\
    /** @return string */
    final public function getConfigDir()
    {
        return $this->directories->getConfigDir();
    }

    /** @return string */
    final public function getDefaultConfigDirectory()
    {
        return $this->directories->getDefaultConfigDir();
    }

    /** @return string */
    private function getEnvironment()
    {
        return $this->environment;
    }

    /** @return string */
    public function getProjectDir()
    {
        return $this->directories->getProjectDir();
    }

    /** @return string */
    public function getVarDir()
    {
        return $this->directories->getVarDir();
    }

    //////////////////////////////// PUBLIC API \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    final public function __construct(Directories $directories, $environment) {
        $this->directories = $directories;
        $this->environment = $environment;
    }

    /**
     * Load bundles from project configuration
     *
     * @return array|mixed
     * @throws \Symfony\Component\Yaml\Exception\ParseException
     */
    final public function loadBundles()
    {
        $projectBundleConfig = [];
        if (is_readable($this->getConfigDir() . '/bundles.yml')) {
            $projectBundleConfig = Yaml::parse(
                file_get_contents($this->getConfigDir() . '/bundles.yml')
            );

            return $projectBundleConfig;
        }

        return $projectBundleConfig;
    }

    /**
     * @param ContainerBuilder $containerBuilder
     * @param array $defaultConfig
     *
     * @throws \LogicException
     */
    final public function loadDefaultConfiguration(ContainerBuilder $containerBuilder, array $defaultConfig)
    {
        $containerBuilder->loadFromExtension('framework', $defaultConfig);
    }

    /**
     * @param LoaderInterface $loader
     *
     * @throws \Exception
     */
    final public function loadDefaultSecurity(LoaderInterface $loader)
    {
        /* Load default security configuration file */
        if (file_exists($this->getConfigDir() . '/security.yml') === false
            && file_exists($this->getConfigDir() . '/security_' . $this->getEnvironment() . '.yml') === false
        ) {
            $loader->load($this->getDefaultConfigDirectory() . '/security.yml');
        }
    }

    /**
     * @param LoaderInterface $loader
     */
    final public function loadProjectConfig(LoaderInterface $loader)
    {
        /* Load project configuration files */
        $projectConfigFiles = [
            '/config.yml' => '/config_' . $this->getEnvironment() . '.yml',
            '/security.yml' => '/security_' . $this->getEnvironment() . '.yml',
            '/services.yml' => '/services_' . $this->getEnvironment() . '.yml',
        ];
        array_walk($projectConfigFiles, $this->loadConfigIfExists($loader), $this->getConfigDir());
    }

    /**
     * @param LoaderInterface $loader
     */
    final public function loadProjectParameters(LoaderInterface $loader)
    {
        $parametersFile = [
            '/parameters.yml' => '/parameters_'.$this->getEnvironment().'.yml'
        ];

        array_walk($parametersFile, $this->loadConfigIfExists($loader), $this->getConfigDir());
    }

    /**
     * @param ContainerBuilder $containerBuilder
     *
     * @throws \LogicException
     */
    final public function loadRequiredConfig(ContainerBuilder $containerBuilder)
    {
        /*/ Make sure required configuration is set /*/
        $configuration = $this->loadedConfigurations($containerBuilder, 'framework');
        if (array_key_exists('secret', $configuration) === false) {
            $containerBuilder->loadFromExtension('framework', ['secret' => 'S0ME_SECR3T']);
        }
    }

    /**
     * @param RouteCollectionBuilder $router
     */
    final public function loadRoutes(RouteCollectionBuilder $router)
    {
        $routingFiles = ['/routing.yml' => '/routing' . $this->getEnvironment() . '.yml'];

        array_walk($routingFiles, $this->loadRouteIfExists($router), $this->getConfigDir());
    }

    ////////////////////////////// UTILITY METHODS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    private function loadedConfigurations(ContainerBuilder $containerBuilder, $extension)
    {
        $configuration = $containerBuilder->getExtensionConfig($extension);

        /* Flatten Array */
        return iterator_to_array(
            new \RecursiveIteratorIterator(
                new \RecursiveArrayIterator($configuration)
            )
        );
    }

    private function loadConfigIfExists(LoaderInterface $loader)
    {
        return function ($file, $alternativeFile, $directory) use (&$loader) {
            if (is_readable($directory.$file)) {
                $loader->load($directory.$file);
            } elseif (is_numeric($alternativeFile) === false
                && is_readable($directory.$alternativeFile)
            ) {
                $loader->load($directory.$alternativeFile);
            }
        };
    }

    private function loadRouteIfExists(RouteCollectionBuilder $routes)
    {
        return function ($file, $alternativeFile, $directory) use (&$routes) {
            if (is_readable($directory.$file)) {
                $routes->import($directory.$file);
            } elseif (is_readable($directory.$alternativeFile)) {
                $routes->import($directory.$alternativeFile);
            }
        };
    }
}

/*EOF*/


<?php
/**
 * @section LICENSE
 * This file is part of MediaWiki simple i18n.
 *
 * MediaWiki simple i18n is free software: you can redistribute it
 * and/or modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * MediaWiki simple i18n is distributed in the hope that it will
 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with MediaWiki simple i18n.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @file
 */

namespace Wikimedia\SimpleI18n;

use Psr\Log\LoggerInterface;

/**
 * Load messages from JSON files in a given directory.
 *
 * @copyright © 2014 Bryan Davis and Wikimedia Foundation
 */
class JsonCache extends ArrayCache {

	/**
	 * @var LoggerInterface $logger
	 */
	protected $logger;

	/**
	 * @var string $messageDirectory
	 */
	protected $messageDirectory;

	/**
	 * @param string $directory Directory of json message files
	 * @param LoggerInterface $logger
	 */
	public function __construct(
		$directory, LoggerInterface $logger = null
	) {
		$this->logger = $logger ?: new \Psr\Log\NullLogger();
		$this->messageDirectory = $directory;
		if ( !is_dir( $this->messageDirectory ) ) {
			$this->logger->error( 'Directory not found.', array(
				'method' => __METHOD__,
				'messageDirectory' => $this->messageDirectory,
			) );
		}
	}

	/**
	 * Load messages from message directory.
	 */
	protected function loadMessages() {
		if ( $this->messages === null ) {
			$this->messages = array();
			foreach ( glob( "{$this->messageDirectory}/*.json" ) as $file ) {
				$lang = strtolower( substr( basename( $file ), 0, -5 ) );
				if ( $lang === 'qqq' ) {
					// Ignore message documentation
					continue;
				}

				if ( is_readable( $file ) ) {
					$json = file_get_contents( $file );
					if ( $json === false ) {
						$this->logger->error( 'Error reading file', array(
							'method' => __METHOD__,
							'file' => $file,
						) );
						continue;
					}

					$data = json_decode( $json, true );
					if ( $data === null ) {
						$this->logger->error( 'Error parsing json', array(
							'method' => __METHOD__,
							'file' => $file,
							'json_error' => json_last_error(),
						) );
						continue;
					}

					// Discard metadata
					unset( $data['@metadata'] );

					if ( empty( $data ) ) {
						// Ignore empty languages
						continue;
					}

					$this->messages[$lang] = $data;
				}
			}
		}
	}

	public function getAvailableLanguages() {
		$this->loadMessages();
		return parent::getAvailableLanguages();
	}

	public function get( $key, $langs ) {
		$this->loadMessages();
		return parent::get( $key, $langs );
	}
}


<?php

/*
 * This file is part of madewithlove/service-providers
 *
 * (c) madewithlove <heroes@madewithlove.be>
 *
 * For the full copyright and license information, please view the LICENSE
 */

namespace Madewithlove\ServiceProviders\Utilities;

use Interop\Container\ServiceProviderInterface;

/**
 * Prefixes the services of an SP with a prefix.
 */
class PrefixedProvider implements ServiceProviderInterface
{
    /**
     * @var string
     */
    protected $prefix;

    /**
     * @var ServiceProviderInterface
     */
    protected $provider;

    /**
     * @param string                   $prefix
     * @param ServiceProviderInterface $provider
     */
    public function __construct($prefix, ServiceProviderInterface $provider)
    {
        $this->prefix = $prefix;
        $this->provider = $provider;
    }

    /**
     * {@inheritdoc}
     */
    public function getServices()
    {
        $prefixed = [];
        $services = $this->provider->getServices();
        foreach ($services as $key => $value) {
            $prefixed[$this->prefix.'.'.$key] = $value;
        }

        return $prefixed;
    }
}


<?php

/**
 * This file implements the "software requester" for Slim V3.
 */

namespace dbeurive\Slim;

use Slim\Http\Environment;
use Slim\Http\Request;
use Slim\Http\Response;
use Slim\App;

/**
 * Class Requester
 *
 * This class implements the "software requester" for Slim V3.
 *
 * @note If you plan to modify the code of this class, be aware that many Slim methods return "clones" (of the object from which they were called).
 *       That is: the object upon which the method is called is not modified.
 *
 * @package dbeurive\Slim
 */
class Requester
{
    /**
     * @var array HTTP headers (ex: "Content-Length", "Content-Type"...).
     * @see https://developer.mozilla.org/fr/docs/HTTP/Headers
     */
    private $__httpHeaders = array();
    /**
     * @var array Server CGI environment variables (ex: "SERVER_NAME", "QUERY_STRING"...).
     * @see http://php.net/manual/fr/reserved.variables.server.php
     */
    private $__serverCgiEnvironmentVariables = array();
    /**
     * @var App Slim application.
     * @note This variable is used to initialise the container (for the dependency injection).
     */
    private $__application;
    /** @var Request HTTP request. */
    private $__request;
    /** @var Response HTTP response. */
    private $__response;
    /** @var string The text returned by the request. */
    private $__stdout;

    /**
     * SoftRequester constructor.
     *
     * @param App $inApplication The Slim application.
     * @throws \Exception
     */
    public function __construct(App $inApplication)
    {
        $this->__application = $inApplication;
    }

    /**
     * Return the Slim request.
     * @return Request The Slim request.
     */
    public function getRequest() {
        return $this->__request;
    }

    /**
     * Return the Slim response.
     * @return Response The Slim response.
     */
    public function getResponse() {
        return $this->__response;
    }

    /**
     * Set the HTTP headers for the request.
     *
     * @param array $inHttpHeaders The HTTP headers to set.
     *        See {@url https://developer.mozilla.org/fr/docs/HTTP/Headers} for the list of HTTP headers.
     * @param bool $inMerge This parameter determines whether the given list of headers should be merged to the existing one or not.
     *        If the value if false, then the given list of headers will replace the existing one.
     *        Otherwise, the given list of headers will be merged into the existing one.
     * @return $this
     */
    public function setHttpHeaders(array $inHttpHeaders, $inMerge=false) {
        if ($inMerge) {
            $this->__httpHeaders = array_merge($this->__httpHeaders, $inHttpHeaders);
        } else {
            $this->__httpHeaders = $inHttpHeaders;
        }
        return $this;
    }

    /**
     * Set the server CGI environment variables.
     *
     * @param array $inServerCgiEnvironmentVariables
     *        See {@url http://php.net/manual/fr/reserved.variables.server.php} for the list of variables.
     * @param bool $inMerge This parameter determines whether the given list of variables should be merged to the existing one or not.
     *        If the value if false, then the given list of variables will replace the existing one.
     *        Otherwise, the given list of variables will be merged into the existing one.
     * @return $this
     */
    public function setServerCgiEnvironmentVariables(array $inServerCgiEnvironmentVariables, $inMerge=false) {
        if ($inMerge) {
            $this->__serverCgiEnvironmentVariables = array_merge($this->__serverCgiEnvironmentVariables, $inServerCgiEnvironmentVariables);
        } else {
            $this->__serverCgiEnvironmentVariables = $inServerCgiEnvironmentVariables;
        }
        return $this;
    }

    /**
     * Execute a request and return what should have been returned through the standard output.
     * Let's consider a GET HTTP request to the following URL: http://www.google.com/search?req=a&option=2
     * - The request method is "GET" (parameter $inRequestMethod).
     * - The request URI is "/hello/toto" (parameter $inRequestUri).
     * - The query string is "a=1&b=2$c=3" (parameter $inQueryString).
     * - There is no request body.
     *
     * @param string $inRequestMethod HTTP Method to use ('GET', 'POST'...).
     * @param string $inRequestUri The request URI (example: "/hello/toto").
     * @param string $inQueryString The query string (example: "a=1&b=2$c=3").
     * @param string $inRequestBody Request's body to set (for the method POST, typically).
     * @return string The content of the standard output.
     * @throws \Exception
     * @see \Slim\DefaultServicesProvider::register Here you see how the environment is used.
     * @see \Slim\App::run Here, you can print the request's data (from a real request).
     * @see \Slim\Http\Environment
     * @note Please keep in mind that:
     *       - HTTP headers can be configured through the method SoftRequester::setHttpHeaders().
     *       - Server CGI environment variables can be configured through the method SoftRequester::setServerCgiEnvironmentVariables().
     * @see Requester::setHttpHeaders()
     * @see Requester::setServerCgiEnvironmentVariables()
     */
    private function request($inRequestMethod, $inRequestUri, $inQueryString='', $inRequestBody=null) {
        ob_start();

        // Configure the Slim application so that it will use the test environment.
        // See the method \Slim\DefaultServicesProvider::register.
        // $this->__applicationConfiguration['environment'] = $environment;
        // $app = new \Slim\App($this->__application);
        // $container = $app->getContainer();

        $container = $this->__application->getContainer();
        $container['environment'] = Environment::mock(array_merge(array(
            'REQUEST_METHOD' => $inRequestMethod,
            'REQUEST_URI'    => $inRequestUri,
            'QUERY_STRING'   => $inQueryString
        ), $this->__serverCgiEnvironmentVariables));

        // Add middleware, if necessary.

        if (! is_null($inRequestBody)) {
            $this->__application->add(function (Request $request, Response $response, $next) use($inRequestBody) {

                // Set the body.
                $fp = fopen("php://temp", 'r+');
                fwrite($fp, $inRequestBody);
                rewind($fp);
                $body = new \Slim\Http\Body($fp);

                // Please note:
                // \Slim\Http\Message::withBody returns a clone of the request.
                $request = $request->withBody($body);
                $response = $next($request, $response);
                return $response;
            });
        }

        if (count($this->__httpHeaders) > 0) {
            $headers = $this->__httpHeaders;
            $this->__application->add(function (Request $request, Response $response, $next) use($headers) {

                foreach ($headers as $_name => $_value) {
                    // Please note:
                    // \Slim\Http\Message::withHeader returns a clone of the request.
                    $request = $request->withHeader($_name, $_value);
                }

                $response = $next($request, $response);
                return $response;
            });
        }

        // Run the Slim application.
        $this->__application->run();

        // Store the request and the response for later use in the unit tests.
        $this->__request = $this->__application->getContainer()->get('request');
        $this->__response = $this->__application->getContainer()->get('response');

        $this->__stdout = ob_get_clean();
        return $this->__stdout;
    }

    /**
     * Execute a GET request.
     * Let's consider a GET HTTP request to the following URL: http://www.google.com/search?req=a&option=2
     * - The request URI is "/hello/toto" (parameter $inRequestUri).
     * - The query string is "a=1&b=2$c=3" (parameter $inQueryString).
     * - There is no request body.
     *
     * @param string $inRequestUri The request URI (example: "/hello/toto").
     * @param string $inQueryString The query string (example: "a=1&b=2$c=3").
     * @return string The content of the standard output.
     * @note Please keep in mind that:
     *       - HTTP headers can be configured through the method SoftRequester::setHttpHeaders().
     *       - Server CGI environment variables can be configured through the method SoftRequester::setServerCgiEnvironmentVariables().
     * @see Requester::setHttpHeaders()
     * @see Requester::setServerCgiEnvironmentVariables()
     */
    public function get($inRequestUri, $inQueryString='') {
        return $this->request('GET', $inRequestUri, $inQueryString, null);
    }

    /**
     * Execute a POST request.
     *
     * @param string $inRequestUri The request URI (example: "/hello/toto").
     * @param array $inPostParameters List of parameters to pass.
     * @return string The content of the standard output.
     * @see \Slim\Http\Request::getParsedBody for a detailed description of how the request body is parsed.
     *      The parsing relies on the value of the 'Content-Type' header.
     *      It should be "application/x-www-form-urlencoded".
     * @note Please keep in mind that:
     *       - HTTP headers can be configured through the method SoftRequester::setHttpHeaders().
     *       - Server CGI environment variables can be configured through the method SoftRequester::setServerCgiEnvironmentVariables().
     * @see Requester::setHttpHeaders()
     * @see Requester::setServerCgiEnvironmentVariables()

     */
    public function post($inRequestUri, $inPostParameters=[]) {

        // Prepare the content of the request's body.
        $bodyContent = [];
        foreach ($inPostParameters as $_name => $_value) {
            $bodyContent[] = $_name . '=' . urlencode($_value);
        }
        $bodyContent = implode('&', $bodyContent);

        // Prepare the request's headers.
        if (! array_key_exists('Content-Type', $this->__httpHeaders)) {
            $this->__httpHeaders['Content-Type'] = 'application/x-www-form-urlencoded';
        }
        if (! array_key_exists('Content-Length', $this->__httpHeaders)) {
            $this->__httpHeaders['Content-Length'] = strlen($bodyContent);
        }

        return $this->request('POST', $inRequestUri, '', $bodyContent);
    }

    /**
     * Send a JSON RPC request.
     *
     * @param string $inRequestUri The request URI (example: "/hello/toto").
     * @param array $inParameters The structure that will be converted into JSON, and that contains the data to send.
     * @return string string The content of the standard output.
     * @note Please keep in mind that:
     *       - HTTP headers can be configured through the method SoftRequester::setHttpHeaders().
     *       - Server CGI environment variables can be configured through the method SoftRequester::setServerCgiEnvironmentVariables().
     * @see Requester::setHttpHeaders()
     * @see Requester::setServerCgiEnvironmentVariables()
     */
    public function jsonRpc($inRequestUri, $inParameters=[]) {
        $bodyContent = json_encode($inParameters);

        // Prepare the request's headers.
        if (! array_key_exists('Content-Type', $this->__httpHeaders)) {
            $this->__httpHeaders['Content-Type'] = 'application/jsonrequest';
        }
        if (! array_key_exists('Accept', $this->__httpHeaders)) {
            $this->__httpHeaders['Accept'] = 'application/jsonrequest';
        }
        if (! array_key_exists('Content-Length', $this->__httpHeaders)) {
            $this->__httpHeaders['Content-Length'] = strlen($bodyContent);
        }
        return $this->request('POST', $inRequestUri, '', $bodyContent);
    }
}


<?php
/**
 * This file is part of the CarteBlanche PHP framework.
 *
 * (c) Pierre Cassat <me@e-piwi.fr> and contributors
 *
 * License Apache-2.0 <http://github.com/php-carteblanche/carteblanche/blob/master/LICENSE>
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CarteBlanche\Library\StorageEngine\DatabaseDriver;

use \CarteBlanche\CarteBlanche;
use \CarteBlanche\Library\StorageEngine\DatabaseDriver\AbstractDatabaseDriver;
use \CarteBlanche\Library\StorageEngine\DatabaseDriver\DatabaseDriverInterface;

/**
 * Database full driver
 *
 * SQLite DataBase driver
 *
 * @TODO    rewrite the whole class with SQLite3
 *
 * @author  Piero Wbmstr <me@e-piwi.fr>
 */
class SqliteDriver
    extends AbstractDatabaseDriver
    implements DatabaseDriverInterface
{

// ------------------------
// Properties
// ------------------------

    protected $db_name;
    protected $db_options;
    protected $db;
    protected $db_driver;

// ------------------------
// Construction
// ------------------------

    public function __construct(\CarteBlanche\Library\StorageEngine\Database $db_driver, $db_name, $db_options = null)
    {
        $this->db_driver = $db_driver;
        $this->db_name = (isset($db_options['path']) ? $db_options['path'] : '').$db_name;
        if (!empty($db_options) && is_array($db_options))
            $this->db_options = $db_options;
        else
            $this->db_options = array();
        $this->_loadStatics();
    }

    protected function _loadStatics()
    {
        parent::_buildStatics(array(
            'assoc'=>SQLITE_ASSOC,
            'num'=>SQLITE_NUM,
            'both'=>SQLITE_BOTH
        ));
    }

// ------------------------
// Connexion
// ------------------------

    /**
     * Connexion to the BDD
     */
    public function connect()
    {
/*
        $this->db = new \SQLiteDatabase(
            $this->db_name,
            isset($this->db_options['chmod']) ? $this->db_options['chmod'] : 0644,
            $err
        );
        if ($err) throw new ErrorException(
            sprintf('Can not connect or create SQLite database "%s" [%s]!', $this->db_name, $err)
        );
*/
        try {
            $this->db = new \SQLite3($this->db_name);
        } catch (\Exception $e) {
            throw $e;
        }

        $this->db_name = str_replace(array(
            CarteBlanche::getPath('root_path'),
            CarteBlanche::getPath('db_dir')
        ), '', $this->db_name);
        return $this->db;
    }

    /**
     * Close the connexion to the BDD
     */
    public function disconnect()
    {
        sqlite_close( $this->db );
    }

// ------------------------
// Query execution
// ------------------------

    /**
     * Execute a single query
     *
     * @param string $query The query string to execute
     * @param bool $cached If set to TRUE (default), the query results are first searched in the object cache
     * @return mixed The query result(s)
     * @see http://www.php.net/manual/en/function.sqlite-single-query.php
     */
    public function singleQuery($query = null, $cached = true)
    {
        if ($cached===true && $this->db_driver->isCachedQuery($query))
            return $this->db_driver->getCachedResults( $query );

        $err = null;
        $results = $this->db->singleQuery($query, $err);
        if ($err) trigger_error( "Error on query '{$query}' [$err]!", E_USER_ERROR);
        $this->db_driver->addCachedQuery( $query, $results );
        return $results;
    }

    /**
     * Execute a query
     *
     * @param string $query The query string to execute
     * @param string $type The query type (see php documentation)
     * @param string $method The query method to use
     * @param bool $cached If set to TRUE (default), the query results are first searched in the object cache
     * @return mixed The query result(s)
     * @see http://www.php.net/manual/en/function.sqlite-query.php
     */
    public function query($query = null, $type = null, $method = 'query', $cached = true)
    {
        if (is_null($type)) $type = self::$DBADAPTER_BOTH;

        if ($cached===true && $this->db_driver->isCachedQuery($query))
            return $this->db_driver->getCachedResults( $query );

        $err = null;
        $results = $this->db->{$method}($query, $type, $err);
        if ($err) trigger_error( "Error on query '{$query}' [$err]!", E_USER_ERROR);
        $this->db_driver->addCachedQuery( $query, $results );
        return $results;
    }

    /**
     * Execute an array query
     *
     * @param string $query The query string to execute
     * @param string $method The query method to use
     * @param bool $cached If set to TRUE (default), the query results are first searched in the object cache
     * @return mixed The query result(s)
     * @see http://www.php.net/manual/en/function.sqlite-array-query.php
     */
    public function arrayQuery($query = null, $method = 'arrayQuery', $cached = true )
    {
        if ($cached===true && $this->db_driver->isCachedQuery($query))
            return $this->db_driver->getCachedResults( $query );

        $err = null;
        $results = $this->db->{$method}($query, $err);
        if ($err) trigger_error( "Error on query '{$query}' [$err]!", E_USER_ERROR);
        $this->db_driver->addCachedQuery( $query, $results );
        return $results;
    }

    /**
     * Get the primary ID of the last insertion
     */
    public function lastInsertId()
    {
        return $this->db->lastInsertRowid();
    }

    /**
     * Escape a string using the internal PHP sqlite function
     *
     * @param string $str The string to escape
     * @param bool $double_quotes If true, the double-quotes will be doubled for escaping
     * @return string The escaped string
     * @see http://www.php.net/manual/en/function.sqlite-escape-string.php
     */
    static function escape($str = null, $double_quotes = false)
    {
        return sqlite_escape_string(
            true===$double_quotes ? str_replace('"', '""', $str) : $str
        );
    }

}

// Endfile


<?php

/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Filter
 * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Digits.php 24593 2012-01-05 20:35:02Z matthew $
 */

/**
 * @see Zend_Filter_Interface
 */

/**
 * @category   Zend
 * @package    Zend_Filter
 * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Filter_Digits implements Zend_Filter_Interface
{
    /**
     * Is PCRE is compiled with UTF-8 and Unicode support
     *
     * @var mixed
     **/
    protected static $_unicodeEnabled;

    /**
     * Class constructor
     *
     * Checks if PCRE is compiled with UTF-8 and Unicode support
     *
     * @return void
     */
    public function __construct()
    {
        if (null === self::$_unicodeEnabled) {
            self::$_unicodeEnabled = (@preg_match('/\pL/u', 'a')) ? true : false;
        }
    }

    /**
     * Defined by Zend_Filter_Interface
     *
     * Returns the string $value, removing all but digit characters
     *
     * @param  string $value
     * @return string
     */
    public function filter($value)
    {
        if (!self::$_unicodeEnabled) {
            // POSIX named classes are not supported, use alternative 0-9 match
            $pattern = '/[^0-9]/';
        } else if (extension_loaded('mbstring')) {
            // Filter for the value with mbstring
            $pattern = '/[^[:digit:]]/';
        } else {
            // Filter for the value without mbstring
            $pattern = '/[\p{^N}]/';
        }

        return preg_replace($pattern, '', (string) $value);
    }
}


<?php

namespace Reaction\Web;

use Reaction;
use Reaction\Base\BaseObject;
use Reaction\Helpers\ArrayHelper;
use Reaction\Helpers\Url;

/**
 * AssetBundle represents a collection of asset files, such as CSS, JS, images.
 *
 * Each asset bundle has a unique name that globally identifies it among all asset bundles used in an application.
 * The name is the [fully qualified class name](http://php.net/manual/en/language.namespaces.rules.php)
 * of the class representing it.
 *
 * An asset bundle can depend on other asset bundles. When registering an asset bundle
 * with a view, all its dependent asset bundles will be automatically registered.
 *
 * For more details and usage information on AssetBundle, see the [guide article on assets](guide:structure-assets).
 */
class AssetBundle extends BaseObject
{
    /**
     * @var string the directory that contains the source asset files for this asset bundle.
     * A source asset file is a file that is part of your source code repository of your Web application.
     *
     * You must set this property if the directory containing the source asset files is not Web accessible.
     * By setting this property, [[AssetManager]] will publish the source asset files
     * to a Web-accessible directory automatically when the asset bundle is registered on a page.
     *
     * If you do not set this property, it means the source asset files are located under [[basePath]].
     *
     * You can use either a directory or an alias of the directory.
     * @see $publishOptions
     */
    public $sourcePath;
    /**
     * @var string the Web-accessible directory that contains the asset files in this bundle.
     *
     * If [[sourcePath]] is set, this property will be *overwritten* by [[AssetManager]]
     * when it publishes the asset files from [[sourcePath]].
     *
     * You can use either a directory or an alias of the directory.
     */
    public $basePath;
    /**
     * @var string the base URL for the relative asset files listed in [[js]] and [[css]].
     *
     * If [[sourcePath]] is set, this property will be *overwritten* by [[AssetManager]]
     * when it publishes the asset files from [[sourcePath]].
     *
     * You can use either a URL or an alias of the URL.
     */
    public $baseUrl;
    /**
     * @var array list of bundle class names that this bundle depends on.
     *
     * For example:
     *
     * ```php
     * public $depends = [
     *    'yii\web\YiiAsset',
     *    'yii\bootstrap\BootstrapAsset',
     * ];
     * ```
     */
    public $depends = [];
    /**
     * @var array list of JavaScript files that this bundle contains. Each JavaScript file can be
     * specified in one of the following formats:
     *
     * - an absolute URL representing an external asset. For example,
     *   `http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` or
     *   `//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js`.
     * - a relative path representing a local asset (e.g. `js/main.js`). The actual file path of a local
     *   asset can be determined by prefixing [[basePath]] to the relative path, and the actual URL
     *   of the asset can be determined by prefixing [[baseUrl]] to the relative path.
     * - an array, with the first entry being the URL or relative path as described before, and a list of key => value pairs
     *   that will be used to overwrite [[jsOptions]] settings for this entry.
     *   This functionality is available since version 2.0.7.
     *
     * Note that only a forward slash "/" should be used as directory separator.
     */
    public $js = [];
    /**
     * @var array list of CSS files that this bundle contains. Each CSS file can be specified
     * in one of the three formats as explained in [[js]].
     *
     * Note that only a forward slash "/" should be used as directory separator.
     */
    public $css = [];
    /**
     * @var array the options that will be passed to [[View::registerJsFile()]]
     * when registering the JS files in this bundle.
     */
    public $jsOptions = [];
    /**
     * @var array the options that will be passed to [[View::registerCssFile()]]
     * when registering the CSS files in this bundle.
     */
    public $cssOptions = [];
    /**
     * @var array the options to be passed to [[AssetManager::publish()]] when the asset bundle
     * is being published. This property is used only when [[sourcePath]] is set.
     */
    public $publishOptions = [];

    /**
     * Registers this asset bundle with a view.
     * @param View $view the view to be registered with
     * @return static the registered asset bundle instance
     */
    public static function register($view)
    {
        return $view->registerAssetBundle(get_called_class());
    }

    /**
     * Initializes the bundle.
     * If you override this method, make sure you call the parent implementation in the last.
     */
    public function init()
    {
        if ($this->sourcePath !== null) {
            $this->sourcePath = rtrim(Reaction::$app->getAlias($this->sourcePath), '/\\');
        }
        if ($this->basePath !== null) {
            $this->basePath = rtrim(Reaction::$app->getAlias($this->basePath), '/\\');
        }
        if ($this->baseUrl !== null) {
            $this->baseUrl = rtrim(Reaction::$app->getAlias($this->baseUrl), '/');
        }
    }

    /**
     * Registers the CSS and JS files with the given view.
     * @param \Reaction\Web\View $view the view that the asset files are to be registered with.
     */
    public function registerAssetFiles($view)
    {
        $manager = $view->getAssetManager();
        foreach ($this->js as $js) {
            if (is_array($js)) {
                $file = array_shift($js);
                $options = ArrayHelper::merge($this->jsOptions, $js);
                $view->registerJsFile($manager->getAssetUrl($this, $file), $options);
            } else {
                if ($js !== null) {
                    $view->registerJsFile($manager->getAssetUrl($this, $js), $this->jsOptions);
                }
            }
        }
        foreach ($this->css as $css) {
            if (is_array($css)) {
                $file = array_shift($css);
                $options = ArrayHelper::merge($this->cssOptions, $css);
                $view->registerCssFile($manager->getAssetUrl($this, $file), $options);
            } else {
                if ($css !== null) {
                    $view->registerCssFile($manager->getAssetUrl($this, $css), $this->cssOptions);
                }
            }
        }
    }

    /**
     * Publishes the asset bundle if its source code is not under Web-accessible directory.
     * It will also try to convert non-CSS or JS files (e.g. LESS, Sass) into the corresponding
     * CSS or JS files using [[AssetManager::converter|asset converter]].
     * @param AssetManager $am the asset manager to perform the asset publishing
     */
    public function publish($am)
    {
        if ($this->sourcePath !== null && !isset($this->basePath, $this->baseUrl)) {
            list($this->basePath, $this->baseUrl) = $am->publish($this->sourcePath, $this->publishOptions);
        }

        if (isset($this->basePath, $this->baseUrl) && ($converter = $am->getConverter()) !== null) {
            foreach ($this->js as $i => $js) {
                if (is_array($js)) {
                    $file = array_shift($js);
                    if (Url::isRelative($file)) {
                        $js = ArrayHelper::merge($this->jsOptions, $js);
                        array_unshift($js, $converter->convert($file, $this->basePath));
                        $this->js[$i] = $js;
                    }
                } elseif (Url::isRelative($js)) {
                    $this->js[$i] = $converter->convert($js, $this->basePath);
                }
            }
            foreach ($this->css as $i => $css) {
                if (is_array($css)) {
                    $file = array_shift($css);
                    if (Url::isRelative($file)) {
                        $css = ArrayHelper::merge($this->cssOptions, $css);
                        array_unshift($css, $converter->convert($file, $this->basePath));
                        $this->css[$i] = $css;
                    }
                } elseif (Url::isRelative($css)) {
                    $this->css[$i] = $converter->convert($css, $this->basePath);
                }
            }
        }
    }
}


<?php
/**
 * This file is part of the CarteBlanche PHP framework.
 *
 * (c) Pierre Cassat <me@e-piwi.fr> and contributors
 *
 * License Apache-2.0 <http://github.com/php-carteblanche/carteblanche/blob/master/LICENSE>
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CarteBlanche\Model;

/**
 * The default model abstract class
 *
 * Any model must extend this abstract class.
 *
 * @author  Piero Wbmstr <me@e-piwi.fr>
 */
abstract class AbstractModel
{

    /**
     * The name of the model's default table
     */
    var $_table_name;

    /**
     * The structure of the model's default table
     */
    var $_table_structure;

    /**
     * The set of relations for the model objects
     */
    var $_object_relations=array();

    /**
     * The primary ID of the current object
     */
    var $id=null;

    /**
     * The data of the current object
     */
    var $data=null;

// ------------------------------------------
// Abstract methods
// ------------------------------------------

    /**
     * Must return TRUE if the object exists
     *
     * Basically, it returns `TRUE` when the object `ID` is not empty
     */
    abstract function exists();

    /**
     * Sets the object primary ID
     *
     * @param int $id The primary ID of the object
     */
    abstract function setId($id = null);

    /**
     * Gets the object primary ID
     */
    abstract function getId();

    /**
     * Sets the object data
     *
     * @param array $data An array of the object contents
     */
    abstract function setData($data = null);

    /**
     * Gets the object data
     */
    abstract function getData();

    /**
     * Sets one of the object related object
     *
     * @param string $model The name of the related model
     * @param array $data An array of the contents of the related object
     */
    abstract function setRelated($model = null, $data = null);

    /**
     * Gets one of the object related object
     *
     * @param string $model The name of the related model
     */
    abstract function getRelated($model = null);

// ------------------------------------------
// Common Getters
// ------------------------------------------

    /**
     * Gets the table fields list
     *
     * @return array The fields names list as an array
     */
    public function getFieldsList()
    {
        return array_keys($this->_table_structure);
    }

    /**
     * Does the table have a slug field
     *
     * @return bool True if the model has a slug field
     */
    public function hasSlugField()
    {
        foreach($this->_table_structure as $_field=>$field_structure) {
            if (isset($field_structure['slug']) && $field_structure['slug']===true) {
                return true;
            }
        }
        return false;
    }

    /**
     * Gets the table slug field if so
     *
     * @return mixed The slug field name if found, false otherwise
     */
    public function getSlugField()
    {
        foreach($this->_table_structure as $_field=>$field_structure) {
            if (isset($field_structure['slug']) && $field_structure['slug']===true) {
                return $_field;
            }
        }
        return false;
    }

    /**
     * Gets a table special field if found
     *
     * @param string $field The field name to search
     * @param mixed $value The corresponding value of the field
     * @return array The special search fields list if found
     */
    public function getSpecialFields($field, $value = true)
    {
        $fields = array();
        foreach($this->_table_structure as $_field=>$field_structure) {
            if (isset($field_structure[$field]) && $field_structure[$field]===$value) {
                $fields[] = $_field;
            }
        }
        return $fields;
    }

    /**
     * Gets a list of fields by their type
     *
     * @param string $type The field's type to search
     * @return array The array of the fields matching the type if found
     */
    public function getFieldsByType($type)
    {
        $fields = array();
        foreach($this->_table_structure as $_field=>$field_structure) {
            if (isset($field_structure['type']) && $field_structure['type']==$type) {
                $fields[] = $_field;
            }
        }
        return $fields;
    }

    /**
     * Gets the table name
     *
     * @return string The table name
     */
    public function getTableName()
    {
        return $this->_table_name;
    }

    /**
     * Gets the table structure
     *
     * @return array The full array of the table structure
     */
    public function getTableStructure()
    {
        return $this->_table_structure;
    }

    /**
     * Get a clone of an object
     *
     * @return object A clone of the current object
     * @throws \RuntimeException if the object doesn't exist
     */
    public function getClone()
    {
        if (self::exists()) {
            return clone $this;
        } else {
            throw new \RuntimeException( "Trying to clone an empty object [{$this->_table_name}]!" );
        }
    }

    /**
     * Get a clone of the model (*anything concerning the object itself will be empty*)
     *
     * @return object A clone of the model with ID and Data empty
     */
    public function getModelClone()
    {
        $_this = clone $this;
        if ($_this->exists()) $_this->id=$_this->data=null;
        return $_this;
    }

    /**
     * Get the current date
     */
    public static function getNow()
    {
        return date('Y-m-d H:i:s');
    }

}

// Endfile


<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */

/**
 * Part of HTTP2
 *
 * PHP version 5
 *
 * @category  HTTP
 * @package   HTTP2
 * @author    Stig Bakken <ssb@fast.no>
 * @author    Sterling Hughes <sterling@php.net>
 * @author    Tomas V.V.Cox <cox@idecnet.com>
 * @author    Richard Heyes <richard@php.net>
 * @author    Philippe Jausions <jausions@php.net>
 * @author    Michael Wallner <mike@php.net>
 * @copyright 2002-2008 The Authors
 * @license   http://www.opensource.org/licenses/bsd-license.php  New BSD License
 * @link      http://pear.php.net/package/HTTP2
 */

require_once 'HTTP2/Exception.php';

/**
 * Miscellaneous HTTP Utilities
 *
 * PEAR::HTTP2 provides shorthand methods for generating HTTP dates,
 * issueing HTTP HEAD requests, building absolute URIs, firing redirects and
 * negotiating user preferred language.
 *
 * @category HTTP
 * @package  HTTP2
 * @author   Stig Bakken <ssb@fast.no>
 * @author   Sterling Hughes <sterling@php.net>
 * @author   Tomas V.V.Cox <cox@idecnet.com>
 * @author   Richard Heyes <richard@php.net>
 * @author   Philippe Jausions <jausions@php.net>
 * @author   Michael Wallner <mike@php.net>
 * @license  http://www.opensource.org/licenses/bsd-license.php  New BSD License
 * @version  Release: 1.1.1
 * @link     http://pear.php.net/package/HTTP2
 */
class HTTP2
{
    /**
     * Formats a RFC compliant GMT date HTTP header.  This function honors the
     * "y2k_compliance" php.ini directive and formats the GMT date corresponding
     * to either RFC850 or RFC822.
     *
     * @param mixed $time unix timestamp or date (default = current time)
     *
     * @return string|boolean GMT date string, or FALSE for an invalid
     *                        $time parameter
     */
    public function date($time = null)
    {
        if (!isset($time)) {
            $time = time();
        } elseif (!is_numeric($time) && (-1 === $time = strtotime($time))) {
            return false;
        }

        // RFC822 or RFC850
        $format = ini_get('y2k_compliance') ? 'D, d M Y' : 'l, d-M-y';

        return gmdate($format .' H:i:s \G\M\T', $time);
    }

    /**
     * Negotiates language with the user's browser through the Accept-Language
     * HTTP header or the user's host address.  Language codes are generally in
     * the form "ll" for a language spoken in only one country, or "ll-CC" for a
     * language spoken in a particular country.  For example, U.S. English is
     * "en-US", while British English is "en-UK".  Portugese as spoken in
     * Portugal is "pt-PT", while Brazilian Portugese is "pt-BR".
     *
     * Quality factors in the Accept-Language: header are supported, e.g.:
     *      Accept-Language: en-UK;q=0.7, en-US;q=0.6, no, dk;q=0.8
     *
     *
     *  require_once 'HTTP2.php';
     *  $http = new HTTP2();
     *  $langs = array(
     *      'en'    => 'locales/en',
     *      'en-US' => 'locales/en',
     *      'en-UK' => 'locales/en',
     *      'de'    => 'locales/de',
     *      'de-DE' => 'locales/de',
     *      'de-AT' => 'locales/de',
     *  );
     *  $neg = $http->negotiateLanguage($langs);
     *  $dir = $langs[$neg];
     *
     *
     * @param array  $supported An associative array of supported languages,
     *                          whose values must evaluate to true.
     * @param string $default   The default language to use if none is found.
     *
     * @return string The negotiated language result or the supplied default.
     */
    public function negotiateLanguage($supported, $default = 'en-US')
    {
        $supp = array();
        foreach ($supported as $lang => $isSupported) {
            if ($isSupported) {
                $supp[strtolower($lang)] = $lang;
            }
        }

        if (!count($supp)) {
            return $default;
        }

        if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
            $match = $this->matchAccept(
                $_SERVER['HTTP_ACCEPT_LANGUAGE'],
                $supp
            );
            if (!is_null($match)) {
                return $match;
            }
        }

        if (isset($_SERVER['REMOTE_HOST'])) {
            $lang = strtolower(end($h = explode('.', $_SERVER['REMOTE_HOST'])));
            if (isset($supp[$lang])) {
                return $supp[$lang];
            }
        }

        return $default;
    }

    /**
     * Negotiates charset with the user's browser through the Accept-Charset
     * HTTP header.
     *
     * Quality factors in the Accept-Charset: header are supported, e.g.:
     *      Accept-Language: en-UK;q=0.7, en-US;q=0.6, no, dk;q=0.8
     *
     *
     *  require_once 'HTTP2.php';
     *  $http = new HTTP2();
     *  $charsets = array(
     *      'UTF-8',
     *      'ISO-8859-1',
     *  );
     *  $charset = $http->negotiateCharset($charsets);
     *
     *
     * @param array  $supported An array of supported charsets
     * @param string $default   The default charset to use if none is found.
     *
     * @return string The negotiated language result or the supplied default.
     * @author Philippe Jausions <jausions@php.net>
     */
    public function negotiateCharset($supported, $default = 'ISO-8859-1')
    {
        $supp = array();
        foreach ($supported as $charset) {
            $supp[strtolower($charset)] = $charset;
        }

        if (!count($supp)) {
            return $default;
        }

        if (isset($_SERVER['HTTP_ACCEPT_CHARSET'])) {
            $match = $this->matchAccept(
                $_SERVER['HTTP_ACCEPT_CHARSET'],
                $supp
            );

            if (!is_null($match)) {
                return $match;
            }
        }

        return $default;
    }

    /**
     * Negotiates content type with the user's browser through the Accept
     * HTTP header.
     *
     * Quality factors in the Accept: header are supported, e.g.:
     *      Accept: application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8
     *
     *
     *  require_once 'HTTP2.php';
     *  $http = new HTTP2();
     *  $contentType = array(
     *      'application/xhtml+xml',
     *      'application/xml',
     *      'text/html',
     *      'text/plain',
     *  );
     *  $mime = $http->negotiateMimeType($contentType);
     *
     *
     * @param array  $supported An associative array of supported MIME types.
     * @param string $default   The default type to use if none match.
     *
     * @return string The negotiated MIME type result or the supplied default.
     * @author Philippe Jausions <jausions@php.net>
     */
    public function negotiateMimeType($supported, $default)
    {
        $supp = array();
        foreach ($supported as $type) {
            $supp[strtolower($type)] = $type;
        }

        if (!count($supp)) {
            return $default;
        }

        if (isset($_SERVER['HTTP_ACCEPT'])) {
            $accepts = $this->sortAccept($_SERVER['HTTP_ACCEPT']);

            foreach ($accepts as $type => $q) {
                if (substr($type, -2) != '/*') {
                    if (isset($supp[$type])) {
                        return $supp[$type];
                    }
                    continue;
                }
                if ($type == '*/*') {
                    return array_shift($supp);
                }
                list($general, $specific) = explode('/', $type);
                $general .= '/';
                $len = strlen($general);
                foreach ($supp as $mime => $t) {
                    if (strncasecmp($general, $mime, $len) == 0) {
                        return $t;
                    }
                }
            }
        }

        return $default;
    }

    /**
     * Parses a weighed "Accept" HTTP header and matches it against a list
     * of supported options
     *
     * @param string $header    The HTTP "Accept" header to parse
     * @param array  $supported A list of supported values
     *
     * @return string|NULL a matched option, or NULL if no match
     */
    protected function matchAccept($header, $supported)
    {
        $matches = $this->sortAccept($header);
        foreach ($matches as $key => $q) {
            if (isset($supported[$key])) {
                return $supported[$key];
            }
        }
        // If any (i.e. "*") is acceptable, return the first supported format
        if (isset($matches['*'])) {
            return array_shift($supported);
        }
        return null;
    }

    /**
     * Parses and sorts a weighed "Accept" HTTP header
     *
     * @param string $header The HTTP "Accept" header to parse
     *
     * @return array Sorted list of "accept" options
     */
    protected function sortAccept($header)
    {
        $matches = array();
        foreach (explode(',', $header) as $option) {
            $option = array_map('trim', explode(';', $option));

            $l = strtolower($option[0]);
            if (isset($option[1])) {
                $q = (float) str_replace('q=', '', $option[1]);
            } else {
                $q = null;
                // Assign default low weight for generic values
                if ($l == '*/*') {
                    $q = 0.01;
                } elseif (substr($l, -1) == '*') {
                    $q = 0.02;
                }
            }
            // Unweighted values, get high weight by their position in the
            // list
            $matches[$l] = isset($q) ? $q : 1000 - count($matches);
        }
        arsort($matches, SORT_NUMERIC);
        return $matches;
    }

    /**
     * Sends a "HEAD" HTTP command to a server and returns the headers
     * as an associative array.
     *
     * Example output could be:
     *
     *     Array
     *     (
     *         [response_code] => 200          // The HTTP response code
     *         [response] => HTTP/1.1 200 OK   // The full HTTP response string
     *         [Date] => Fri, 11 Jan 2002 01:41:44 GMT
     *         [Server] => Apache/1.3.20 (Unix) PHP/4.1.1
     *         [X-Powered-By] => PHP/4.1.1
     *         [Connection] => close
     *         [Content-Type] => text/html
     *     )
     *
     *
     * @param string  $url     A valid URL, e.g.: http://pear.php.net/credits.php
     * @param integer $timeout Timeout in seconds (default = 10)
     *
     * @return array Returns associative array of response headers on success
     *
     * @throws HTTP2_Exception          When connecting fails
     * @throws InvalidArgumentException When the protocol is not uspported
     *
     * @see HTTP_Client::head()
     * @see HTTP_Request
     */
    public function head($url, $timeout = 10)
    {
        $p = parse_url($url);
        if (!isset($p['scheme'])) {
            $p = parse_url($this->absoluteURI($url));
        } elseif ($p['scheme'] != 'http') {
            throw new InvalidArgumentException(
                'Unsupported protocol: '. $p['scheme']
            );
        }

        $port = isset($p['port']) ? $p['port'] : 80;

        if (!$fp = @fsockopen($p['host'], $port, $eno, $estr, $timeout)) {
            throw new HTTP2_Exception("Connection error: $estr ($eno)");
        }

        $path  = !empty($p['path']) ? $p['path'] : '/';
        $path .= !empty($p['query']) ? '?' . $p['query'] : '';

        fputs($fp, "HEAD $path HTTP/1.0\r\n");
        fputs($fp, 'Host: ' . $p['host'] . ':' . $port . "\r\n");
        fputs($fp, "Connection: close\r\n\r\n");

        $response = rtrim(fgets($fp, 4096));
        if (preg_match("|^HTTP/[^\s]*\s(.*?)\s|", $response, $status)) {
            $headers['response_code'] = $status[1];
        }
        $headers['response'] = $response;

        while ($line = fgets($fp, 4096)) {
            if (!trim($line)) {
                break;
            }
            if (($pos = strpos($line, ':')) !== false) {
                $header = substr($line, 0, $pos);
                $value  = trim(substr($line, $pos + 1));

                $headers[$header] = $value;
            }
        }
        fclose($fp);
        return $headers;
    }

    /**
     * This function redirects the client. This is done by issuing
     * a "Location" header and exiting if wanted.  If you set $rfc2616 to true
     * HTTP will output a hypertext note with the location of the redirect.
     *
     * @param string $url     URL where the redirect should go to.
     * @param bool   $exit    Whether to exit immediately after redirection.
     * @param bool   $rfc2616 Wheter to output a hypertext note where we're
     *                        redirecting to (Redirecting to
     *                        ....)
     *
     * @return boolean Returns TRUE on succes (or exits) or FALSE if headers
     *                 have already been sent.
     */
    function redirect($url, $exit = true, $rfc2616 = false)
    {
        if (headers_sent()) {
            return false;
        }

        $url = $this->absoluteURI($url);
        header('Location: '. $url);

        if ($rfc2616 && isset($_SERVER['REQUEST_METHOD'])
            && $_SERVER['REQUEST_METHOD'] != 'HEAD'
        ) {
            echo '

Redirecting to: '
                 .htmlspecialchars($url).'.

';
        }
        if ($exit) {
            exit;
        }
        return true;
    }

    /**
     * This function returns the absolute URI for the partial URL passed.
     * The current scheme (HTTP/HTTPS), host server, port, current script
     * location are used if necessary to resolve any relative URLs.
     *
     * Offsets potentially created by PATH_INFO are taken care of to resolve
     * relative URLs to the current script.
     *
     * You can choose a new protocol while resolving the URI.  This is
     * particularly useful when redirecting a web browser using relative URIs
     * and to switch from HTTP to HTTPS, or vice-versa, at the same time.
     *
     * @param string  $url      Absolute or relative URI the redirect should
     *                          go to.
     * @param string  $protocol Protocol to use when redirecting URIs.
     * @param integer $port     A new port number.
     *
     * @return string The absolute URI.
     * @author Philippe Jausions <Philippe.Jausions@11abacus.com>
     */
    public function absoluteURI($url = null, $protocol = null, $port = null)
    {
        // filter CR/LF
        $url = str_replace(array("\r", "\n"), ' ', $url);

        // Mess around protocol and port with already absolute URIs
        if (preg_match('!^([a-z0-9]+)://!i', $url)) {
            if (empty($protocol) && empty($port)) {
                return $url;
            }
            if (!empty($protocol)) {
                $url = $protocol .':'. end($array = explode(':', $url, 2));
            }
            if (!empty($port)) {
                $url = preg_replace(
                    '!^(([a-z0-9]+)://[^/:]+)(:[\d]+)?!i',
                    '\1:'. $port,
                    $url
                );
            }
            return $url;
        }

        $host = 'localhost';
        if (!empty($_SERVER['HTTP_HOST'])) {
            list($host) = explode(':', $_SERVER['HTTP_HOST']);
        } elseif (!empty($_SERVER['SERVER_NAME'])) {
            list($host) = explode(':', $_SERVER['SERVER_NAME']);
        }

        if (empty($protocol)) {
            if (isset($_SERVER['HTTPS']) && !strcasecmp($_SERVER['HTTPS'], 'on')) {
                $protocol = 'https';
            } else {
                $protocol = 'http';
            }
            if (!isset($port) || $port != intval($port)) {
                $port = 80;
                if (isset($_SERVER['SERVER_PORT'])) {
                    $port = $_SERVER['SERVER_PORT'];
                }
            }
        }

        if ($protocol == 'http' && $port == 80) {
            unset($port);
        }
        if ($protocol == 'https' && $port == 443) {
            unset($port);
        }

        $server = $protocol.'://'.$host.(isset($port) ? ':'.$port : '');

        $uriAll = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI']
                                                 : $_SERVER['PHP_SELF'];
        if (false !== ($q = strpos($uriAll, '?'))) {
            $uriBase = substr($uriAll, 0, $q);
        } else {
            $uriBase = $uriAll;
        }
        if (!strlen($url) || $url{0} == '#') {
            $url = $uriAll.$url;
        } elseif ($url{0} == '?') {
            $url = $uriBase.$url;
        }
        if ($url{0} == '/') {
            return $server . $url;
        }

        // Adjust for PATH_INFO if needed
        if (isset($_SERVER['PATH_INFO']) && strlen($_SERVER['PATH_INFO'])) {
            $path = dirname(substr($uriBase, 0, -strlen($_SERVER['PATH_INFO'])));
        } else {
            /**
             * Fixes bug #12672 PHP_SELF ending on / causes incorrect redirects
             *
             * @link http://pear.php.net/bugs/12672
             */
            $path = dirname($uriBase.'-');
        }

        if (substr($path = strtr($path, '\\', '/'), -1) != '/') {
            $path .= '/';
        }

        return $server . $path . $url;
    }

    /**
     * Parses a HTTP "Link" header value as specified by RFC 5988.
     *
     * When errors occur during parsing, all information collected to that
     * point will be returned used and the rest of the line skipped.
     *
     * @param string|array $lines HTTP "Link:" header value (without "Link:"),
     *                            or array of such strings
     *
     * @return array Array of parsed links
     *               (one single line may contain multiple links)
     *               Only params existing in the link are in the array.
     *               URI is available in key "_uri".
     *
     * @link http://tools.ietf.org/html/rfc5988
     */
    public function parseLinks($lines)
    {
        $lines = (array) $lines;
        $extracted = array();

        foreach ($lines as $line) {
            $state = 'uri';
            $pos = 0;
            $len = strlen($line);
            while ($pos < $len - 1) {
                $link = array();
                $pos = $len - strlen(ltrim(substr($line, $pos)));
                if ($line{$pos} == ',') {
                    ++$pos;
                    continue;
                } else if ($line{$pos} != '<') {
                    break;
                }
                $end = strpos($line, '>', $pos + 1);
                if ($end === false) {
                    break;
                }
                $link['_uri'] = substr($line, $pos + 1, $end - $pos - 1);
                $pos = $end + 1;

                while ($pos < $len - 1) {
                    if ($line{$pos} == ',') {
                        $extracted[] = $link;
                        $link = array();
                        ++$pos;
                        continue;
                    } else if ($line{$pos} != ';') {
                        break;
                    }

                    ++$pos;
                    $end = strpos($line, '=', $pos + 1);
                    if ($end === false) {
                        break;
                    }
                    $pname = trim(substr($line, $pos, $end - $pos));
                    $pos = $end + 1;

                    $rest = trim(substr($line, $pos));
                    if ($rest{0} == '"') {
                        $pos = strpos($line, '"', $pos) + 1;
                        $end = strpos($line, '"', $pos + 1);
                        $pval = substr($line, $pos, $end - $pos);
                        $pos = $end + 1;
                    } else {
                        $end1 = strpos($line, ';', $pos + 1);
                        $end2 = strpos($line, ',', $pos + 1);
                        if ($end1 === false && $end2 === false) {
                            $end = $len;
                        } else if ($end1 === false) {
                            $end = $end2;
                        } else if ($end2 === false) {
                            $end = $end1;
                        } else {
                            $end = $end1 < $end2 ? $end1 : $end2;
                        }
                        $pval = trim(substr($line, $pos, $end - $pos));
                        $pos = $end;
                    }
                    if ($pname == 'title*') {
                        $parts = explode("'", $pval, 3);
                        if (count($parts) != 3) {
                            continue;
                        }
                        list($charset, $lang, $val) = $parts;
                        $link[$pname][$lang] = $this->convertCharset(
                            $charset, 'utf-8', urldecode($val)
                        );
                    } else if ($pname == 'rel' || $pname == 'rev') {
                        if (!isset($link[$pname])) {
                            $link[$pname] = array();
                        }
                        $link[$pname] = array_merge(
                            $link[$pname],
                            array_map('trim', explode(' ', $pval))
                        );
                    } else if (!isset($link[$pname])) {
                        $link[$pname] = $pval;
                    }
                    if ($end >= $len || $line{$end} == ',') {
                        break;
                    }
                }
                if (count($link) > 0) {
                    $extracted[] = $link;
                }
            }
        }

        return $extracted;
    }

    /**
     * Convert the given string from one into another charset.
     * Uses mb_convert_encoding or iconv if available.
     *
     * @param string $from Source charset the string is in
     * @param string $to   Target character set
     * @param string $str  String to convert
     *
     * @return string converted string
     */
    protected function convertCharset($from, $to, $str)
    {
        if (function_exists('mb_convert_encoding')) {
            return mb_convert_encoding($str, $to, $from);
        } else if (function_exists('iconv')) {
            return iconv($from, $to, $str);
        }
        return $str;
    }
}
?>