Related
In working on a new cakephp application I get the error message Cannot use 'Object' as class name as it is reserved in C:\projectfolder\ckphp-demo\cake\libs\object.php on line 33.
The project is a legacy web application using cakePHP 1.3.17 with php version PHP 7.4.28 on developement server. see below code for object.php
line 33 is where class Object { starts
<?php
/**
* Object class, allowing __construct and __destruct in PHP4.
*
* Also includes methods for logging and the special method RequestAction,
* to call other Controllers' Actions from anywhere.
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* #copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* #link http://cakephp.org CakePHP(tm) Project
* #package cake
* #subpackage cake.cake.libs
* #since CakePHP(tm) v 0.2.9
* #license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Object class, allowing __construct and __destruct in PHP4.
*
* Also includes methods for logging and the special method RequestAction,
* to call other Controllers' Actions from anywhere.
*
* #package cake
* #subpackage cake.cake.libs
*/
class Object {
/**
* A hack to support __construct() on PHP 4
* Hint: descendant classes have no PHP4 class_name() constructors,
* so this constructor gets called first and calls the top-layer __construct()
* which (if present) should call parent::__construct()
*
* #return Object
*/
function Object() {
$args = func_get_args();
if (method_exists($this, '__destruct')) {
register_shutdown_function (array(&$this, '__destruct'));
}
call_user_func_array(array(&$this, '__construct'), $args);
}
/**
* Class constructor, overridden in descendant classes.
*/
function __construct() {
}
/**
* Object-to-string conversion.
* Each class can override this method as necessary.
*
* #return string The name of this class
* #access public
*/
function toString() {
$class = get_class($this);
return $class;
}
/**
* Calls a controller's method from any location. Can be used to connect controllers together
* or tie plugins into a main application. requestAction can be used to return rendered views
* or fetch the return value from controller actions.
*
* #param mixed $url String or array-based url.
* #param array $extra if array includes the key "return" it sets the AutoRender to true.
* #return mixed Boolean true or false on success/failure, or contents
* of rendered action if 'return' is set in $extra.
* #access public
*/
function requestAction($url, $extra = array()) {
if (empty($url)) {
return false;
}
if (!class_exists('dispatcher')) {
require CAKE . 'dispatcher.php';
}
if (in_array('return', $extra, true)) {
$extra = array_merge($extra, array('return' => 0, 'autoRender' => 1));
}
if (is_array($url) && !isset($extra['url'])) {
$extra['url'] = array();
}
$params = array_merge(array('autoRender' => 0, 'return' => 1, 'bare' => 1, 'requested' => 1), $extra);
$dispatcher = new Dispatcher;
return $dispatcher->dispatch($url, $params);
}
/**
* Calls a method on this object with the given parameters. Provides an OO wrapper
* for `call_user_func_array`
*
* #param string $method Name of the method to call
* #param array $params Parameter list to use when calling $method
* #return mixed Returns the result of the method call
* #access public
*/
function dispatchMethod($method, $params = array()) {
switch (count($params)) {
case 0:
return $this->{$method}();
case 1:
return $this->{$method}($params[0]);
case 2:
return $this->{$method}($params[0], $params[1]);
case 3:
return $this->{$method}($params[0], $params[1], $params[2]);
case 4:
return $this->{$method}($params[0], $params[1], $params[2], $params[3]);
case 5:
return $this->{$method}($params[0], $params[1], $params[2], $params[3], $params[4]);
default:
return call_user_func_array(array(&$this, $method), $params);
break;
}
}
/**
* Stop execution of the current script. Wraps exit() making
* testing easier.
*
* #param $status see http://php.net/exit for values
* #return void
* #access public
*/
function _stop($status = 0) {
exit($status);
}
/**
* Convience method to write a message to CakeLog. See CakeLog::write()
* for more information on writing to logs.
*
* #param string $msg Log message
* #param integer $type Error type constant. Defined in app/config/core.php.
* #return boolean Success of log write
* #access public
*/
function log($msg, $type = LOG_ERROR) {
if (!class_exists('CakeLog')) {
require LIBS . 'cake_log.php';
}
if (!is_string($msg)) {
$msg = print_r($msg, true);
}
return CakeLog::write($type, $msg);
}
/**
* Allows setting of multiple properties of the object in a single line of code. Will only set
* properties that are part of a class declaration.
*
* #param array $properties An associative array containing properties and corresponding values.
* #return void
* #access protected
*/
function _set($properties = array()) {
if (is_array($properties) && !empty($properties)) {
$vars = get_object_vars($this);
foreach ($properties as $key => $val) {
if (array_key_exists($key, $vars)) {
$this->{$key} = $val;
}
}
}
}
/**
* Used to report user friendly errors.
* If there is a file app/error.php or app/app_error.php this file will be loaded
* error.php is the AppError class it should extend ErrorHandler class.
*
* #param string $method Method to be called in the error class (AppError or ErrorHandler classes)
* #param array $messages Message that is to be displayed by the error class
* #return error message
* #access public
*/
function cakeError($method, $messages = array()) {
if (!class_exists('ErrorHandler')) {
App::import('Core', 'Error');
if (file_exists(APP . 'error.php')) {
include_once (APP . 'error.php');
} elseif (file_exists(APP . 'app_error.php')) {
include_once (APP . 'app_error.php');
}
}
if (class_exists('AppError')) {
$error = new AppError($method, $messages);
} else {
$error = new ErrorHandler($method, $messages);
}
return $error;
}
/**
* Checks for a persistent class file, if found file is opened and true returned
* If file is not found a file is created and false returned
* If used in other locations of the model you should choose a unique name for the persistent file
* There are many uses for this method, see manual for examples
*
* #param string $name name of the class to persist
* #param string $object the object to persist
* #return boolean Success
* #access protected
* #todo add examples to manual
*/
function _persist($name, $return = null, &$object, $type = null) {
$file = CACHE . 'persistent' . DS . strtolower($name) . '.php';
if ($return === null) {
if (!file_exists($file)) {
return false;
} else {
return true;
}
}
if (!file_exists($file)) {
$this->_savePersistent($name, $object);
return false;
} else {
$this->__openPersistent($name, $type);
return true;
}
}
/**
* You should choose a unique name for the persistent file
*
* There are many uses for this method, see manual for examples
*
* #param string $name name used for object to cache
* #param object $object the object to persist
* #return boolean true on save, throws error if file can not be created
* #access protected
*/
function _savePersistent($name, &$object) {
$file = 'persistent' . DS . strtolower($name) . '.php';
$objectArray = array(&$object);
$data = str_replace('\\', '\\\\', serialize($objectArray));
$data = '<?php $' . $name . ' = \'' . str_replace('\'', '\\\'', $data) . '\' ?>';
$duration = '+999 days';
if (Configure::read() >= 1) {
$duration = '+10 seconds';
}
cache($file, $data, $duration);
}
/**
* Open the persistent class file for reading
* Used by Object::_persist()
*
* #param string $name Name of persisted class
* #param string $type Type of persistance (e.g: registry)
* #return void
* #access private
*/
function __openPersistent($name, $type = null) {
$file = CACHE . 'persistent' . DS . strtolower($name) . '.php';
include($file);
switch ($type) {
case 'registry':
$vars = unserialize(${$name});
foreach ($vars['0'] as $key => $value) {
if (strpos($key, '_behavior') !== false) {
App::import('Behavior', Inflector::classify(substr($key, 0, -9)));
} else {
App::import('Model', Inflector::camelize($key));
}
unset ($value);
}
unset($vars);
$vars = unserialize(${$name});
foreach ($vars['0'] as $key => $value) {
ClassRegistry::addObject($key, $value);
unset ($value);
}
unset($vars);
break;
default:
$vars = unserialize(${$name});
$this->{$name} = $vars['0'];
unset($vars);
break;
}
}
}
I work on Laravel framework for a short time, after finishing the website, I willing to encode it using Ioncube - but I face the problem where Ioncube can't translate the blade template engine code to PHP code before encoding and output the code as HTML normal text.
Laravel's blade template files are not real PHP code, therefore the ionCube Encoder cannot encode them properly; however, the Encoder also offers file encryption which might help in your case, but it does require a bit of a setup:
In Laravel, modify the module that reads in the Blade template files, replacing file_get_contents(<blade template files>) with ioncube_read_file(<blade template_files>).
In my Laravel 4 installation, it seems like the file responsible for loading and compiling Blade Templates can be found in vendor/laravel/framework/src/Illuminate/View/Compilers/BladeCompiler.php, line 62: $contents = $this->compileString($this->files->get($path));.
Here, $this->files->get($path) is 'just' a file_get_contents($path) with some error handling - you may find this function in bootstrap/compiled.php. However, you should be able to replace the line in BladeCompiler.php with:
$contents = $this->compileString(ioncube_read_file($path));
or (if you used a passphrase):
$passphrase = "<my passphrase>";
$contents = $this->compileString(ioncube_read_file($path, $is_encrypted, $passphrase));
Please do note that you might want to make sure that the passphrase is secure within the file. You can find more information on these functions in the User Guide on page 54.
To get ioncube_read_file working, you will need to encode the modified module. Furthermore, encode the rest of your application with the exception of your Blade template files.
Encrypt (not encode!) your Blade template files, typically ending in .blade.php, and - if you use a passphrase - make sure it matches the one used for ioncube_read_file.
Please also keep in mind that this will generate standard PHP files from your encrypted ones, since the file is compiled and written back to the cache as plain text. If you want to change that it might be worth looking into the User Guide, p. 54 and override / extend the appropriate methods bootstrap/compiled.php such as get and put to detect if a file is encrypted, and to write an encrypted file if needed.
I should also mention, as this question is regularly asked on the ionCube HelpDesk: Despite all the encoding and encrypting, the HTML and JavaScript code will be displayed raw for all clients to see. I only mention this because it is a lot of effort to protect your Template files, which do consist in most cases mostly of HTML code. It does make any modification really hard (such as logo removal), but such things may also be achieved with some custom CSS.
After coming across this issue I believe this answer will be the simple and easy way to solve it. With this methode you won't have to edit framework files every after update.
Create your own new Service Provider to replace ViewServiceProvider. Name it IonCubeCompilerServiceProvider
Create new Class to extend BladeCompiler. Name it IonCubeBladeCompiler
Finally, swap the Illuminate\View\ViewServiceProvider::class out of the config/app.php providers array, and replace it with your own ViewServiceProvider.
namespace App\Providers;
use App\Libraries\IonCubeBladeCompiler;
use Illuminate\View\Engines\CompilerEngine;
use Illuminate\View\ViewServiceProvider;
class IonCubeCompilerServiceProvider extends ViewServiceProvider
{
public function registerBladeEngine($resolver)
{
$this->app->singleton('blade.compiler', function () {
return new IonCubeBladeCompiler(
$this->app['files'], $this->app['config']['view.compiled']
);
});
$resolver->register('blade', function () {
return new CompilerEngine($this->app['blade.compiler']);
});
}
}
Second file.
namespace App\Libraries;
use Illuminate\View\Compilers\BladeCompiler;
class IonCubeBladeCompiler extends BladeCompiler
{
public function compile($path = null)
{
if ($path) {
$this->setPath($path);
}
if (! is_null($this->cachePath)) {
if(function_exists('ioncube_read_file')){
//This is what I'm adding.
$contents = $this->compileString(ioncube_read_file($this->getPath()));
}else{
//This is the original line.
$contents = $this->compileString($this->files->get($this->getPath()));
}
$this->files->put($this->getCompiledPath($this->getPath()), $contents);
}
}
}
For more details you can check the following two links
https://laracasts.com/discuss/channels/laravel/extend-the-compile-function-on-bladecompilerphp
and
http://blog.ioncube.com/2016/12/19/ioncube-encoding-laravel-project-controllers-models-templates/
I created class:
<?php
namespace App\Classes\Compiler;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\View\Compilers\Compiler;
use Illuminate\View\Compilers\CompilerInterface;
class CustomCompiler extends Compiler implements CompilerInterface
{
/**
* All of the registered extensions.
*
* #var array
*/
protected $extensions = [];
/**
* All custom "directive" handlers.
*
* This was implemented as a more usable "extend" in 5.1.
*
* #var array
*/
protected $customDirectives = [];
/**
* The file currently being compiled.
*
* #var string
*/
protected $path;
/**
* All of the available compiler functions.
*
* #var array
*/
protected $compilers = [
'Extensions',
'Statements',
'Comments',
'Echos',
];
/**
* Array of opening and closing tags for raw echos.
*
* #var array
*/
protected $rawTags = ['{!!', '!!}'];
/**
* Array of opening and closing tags for regular echos.
*
* #var array
*/
protected $contentTags = ['{{', '}}'];
/**
* Array of opening and closing tags for escaped echos.
*
* #var array
*/
protected $escapedTags = ['{{{', '}}}'];
/**
* The "regular" / legacy echo string format.
*
* #var string
*/
protected $echoFormat = 'e(%s)';
/**
* Array of footer lines to be added to template.
*
* #var array
*/
protected $footer = [];
/**
* Placeholder to temporary mark the position of verbatim blocks.
*
* #var string
*/
protected $verbatimPlaceholder = '#__verbatim__#';
/**
* Array to temporary store the verbatim blocks found in the template.
*
* #var array
*/
protected $verbatimBlocks = [];
/**
* Counter to keep track of nested forelse statements.
*
* #var int
*/
protected $forelseCounter = 0;
/**
* Compile the view at the given path.
*
* #param string $path
* #return void
*/
public function compile($path = null)
{
if ($path) {
$this->setPath($path);
}
if (! is_null($this->cachePath)) {
if (function_exists('ioncube_read_file')) {
$contents = $this->compileString(ioncube_read_file($this->getPath()));
}
else {
$contents = $this->compileString($this->files->get($this->getPath()));
}
$this->files->put($this->getCompiledPath($this->getPath()), $contents);
}
}
/**
* Get the path currently being compiled.
*
* #return string
*/
public function getPath()
{
return $this->path;
}
/**
* Set the path currently being compiled.
*
* #param string $path
* #return void
*/
public function setPath($path)
{
$this->path = $path;
}
/**
* Compile the given Blade template contents.
*
* #param string $value
* #return string
*/
public function compileString($value)
{
$result = '';
if (strpos($value, '#verbatim') !== false) {
$value = $this->storeVerbatimBlocks($value);
}
$this->footer = [];
// Here we will loop through all of the tokens returned by the Zend lexer and
// parse each one into the corresponding valid PHP. We will then have this
// template as the correctly rendered PHP that can be rendered natively.
foreach (token_get_all($value) as $token) {
$result .= is_array($token) ? $this->parseToken($token) : $token;
}
if (! empty($this->verbatimBlocks)) {
$result = $this->restoreVerbatimBlocks($result);
}
// If there are any footer lines that need to get added to a template we will
// add them here at the end of the template. This gets used mainly for the
// template inheritance via the extends keyword that should be appended.
if (count($this->footer) > 0) {
$result = ltrim($result, PHP_EOL)
.PHP_EOL.implode(PHP_EOL, array_reverse($this->footer));
}
return $result;
}
/**
* Store the verbatim blocks and replace them with a temporary placeholder.
*
* #param string $value
* #return string
*/
protected function storeVerbatimBlocks($value)
{
return preg_replace_callback('/(?<!#)#verbatim(.*?)#endverbatim/s', function ($matches) {
$this->verbatimBlocks[] = $matches[1];
return $this->verbatimPlaceholder;
}, $value);
}
/**
* Replace the raw placeholders with the original code stored in the raw blocks.
*
* #param string $result
* #return string
*/
protected function restoreVerbatimBlocks($result)
{
$result = preg_replace_callback('/'.preg_quote($this->verbatimPlaceholder).'/', function () {
return array_shift($this->verbatimBlocks);
}, $result);
$this->verbatimBlocks = [];
return $result;
}
/**
* Parse the tokens from the template.
*
* #param array $token
* #return string
*/
protected function parseToken($token)
{
list($id, $content) = $token;
if ($id == T_INLINE_HTML) {
foreach ($this->compilers as $type) {
$content = $this->{"compile{$type}"}($content);
}
}
return $content;
}
/**
* Execute the user defined extensions.
*
* #param string $value
* #return string
*/
protected function compileExtensions($value)
{
foreach ($this->extensions as $compiler) {
$value = call_user_func($compiler, $value, $this);
}
return $value;
}
/**
* Compile Blade comments into valid PHP.
*
* #param string $value
* #return string
*/
protected function compileComments($value)
{
$pattern = sprintf('/%s--(.*?)--%s/s', $this->contentTags[0], $this->contentTags[1]);
return preg_replace($pattern, '', $value);
}
/**
* Compile Blade echos into valid PHP.
*
* #param string $value
* #return string
*/
protected function compileEchos($value)
{
foreach ($this->getEchoMethods() as $method => $length) {
$value = $this->$method($value);
}
return $value;
}
/**
* Get the echo methods in the proper order for compilation.
*
* #return array
*/
protected function getEchoMethods()
{
$methods = [
'compileRawEchos' => strlen(stripcslashes($this->rawTags[0])),
'compileEscapedEchos' => strlen(stripcslashes($this->escapedTags[0])),
'compileRegularEchos' => strlen(stripcslashes($this->contentTags[0])),
];
uksort($methods, function ($method1, $method2) use ($methods) {
// Ensure the longest tags are processed first
if ($methods[$method1] > $methods[$method2]) {
return -1;
}
if ($methods[$method1] < $methods[$method2]) {
return 1;
}
// Otherwise give preference to raw tags (assuming they've overridden)
if ($method1 === 'compileRawEchos') {
return -1;
}
if ($method2 === 'compileRawEchos') {
return 1;
}
if ($method1 === 'compileEscapedEchos') {
return -1;
}
if ($method2 === 'compileEscapedEchos') {
return 1;
}
});
return $methods;
}
/**
* Compile Blade statements that start with "#".
*
* #param string $value
* #return mixed
*/
protected function compileStatements($value)
{
$callback = function ($match) {
if (Str::contains($match[1], '#')) {
$match[0] = isset($match[3]) ? $match[1].$match[3] : $match[1];
} elseif (isset($this->customDirectives[$match[1]])) {
$match[0] = $this->callCustomDirective($match[1], Arr::get($match, 3));
} elseif (method_exists($this, $method = 'compile'.ucfirst($match[1]))) {
$match[0] = $this->$method(Arr::get($match, 3));
}
return isset($match[3]) ? $match[0] : $match[0].$match[2];
};
return preg_replace_callback('/\B#(#?\w+(?:::\w+)?)([ \t]*)(\( ( (?>[^()]+) | (?3) )* \))?/x', $callback, $value);
}
/**
* Compile the "raw" echo statements.
*
* #param string $value
* #return string
*/
protected function compileRawEchos($value)
{
$pattern = sprintf('/(#)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->rawTags[0], $this->rawTags[1]);
$callback = function ($matches) {
$whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
return $matches[1] ? substr($matches[0], 1) : '<?php echo '.$this->compileEchoDefaults($matches[2]).'; ?>'.$whitespace;
};
return preg_replace_callback($pattern, $callback, $value);
}
/**
* Compile the "regular" echo statements.
*
* #param string $value
* #return string
*/
protected function compileRegularEchos($value)
{
$pattern = sprintf('/(#)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->contentTags[0], $this->contentTags[1]);
$callback = function ($matches) {
$whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
$wrapped = sprintf($this->echoFormat, $this->compileEchoDefaults($matches[2]));
return $matches[1] ? substr($matches[0], 1) : '<?php echo '.$wrapped.'; ?>'.$whitespace;
};
return preg_replace_callback($pattern, $callback, $value);
}
/**
* Compile the escaped echo statements.
*
* #param string $value
* #return string
*/
protected function compileEscapedEchos($value)
{
$pattern = sprintf('/(#)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->escapedTags[0], $this->escapedTags[1]);
$callback = function ($matches) {
$whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
return $matches[1] ? $matches[0] : '<?php echo e('.$this->compileEchoDefaults($matches[2]).'); ?>'.$whitespace;
};
return preg_replace_callback($pattern, $callback, $value);
}
/**
* Compile the default values for the echo statement.
*
* #param string $value
* #return string
*/
public function compileEchoDefaults($value)
{
return preg_replace('/^(?=\$)(.+?)(?:\s+or\s+)(.+?)$/s', 'isset($1) ? $1 : $2', $value);
}
/**
* Compile the each statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEach($expression)
{
return "<?php echo \$__env->renderEach{$expression}; ?>";
}
/**
* Compile the inject statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileInject($expression)
{
$segments = explode(',', preg_replace("/[\(\)\\\"\']/", '', $expression));
return '<?php $'.trim($segments[0])." = app('".trim($segments[1])."'); ?>";
}
/**
* Compile the yield statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileYield($expression)
{
return "<?php echo \$__env->yieldContent{$expression}; ?>";
}
/**
* Compile the show statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileShow($expression)
{
return '<?php echo $__env->yieldSection(); ?>';
}
/**
* Compile the section statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileSection($expression)
{
return "<?php \$__env->startSection{$expression}; ?>";
}
/**
* Compile the append statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileAppend($expression)
{
return '<?php $__env->appendSection(); ?>';
}
/**
* Compile the end-section statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndsection($expression)
{
return '<?php $__env->stopSection(); ?>';
}
/**
* Compile the stop statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileStop($expression)
{
return '<?php $__env->stopSection(); ?>';
}
/**
* Compile the overwrite statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileOverwrite($expression)
{
return '<?php $__env->stopSection(true); ?>';
}
/**
* Compile the unless statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileUnless($expression)
{
return "<?php if (! $expression): ?>";
}
/**
* Compile the end unless statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndunless($expression)
{
return '<?php endif; ?>';
}
/**
* Compile the lang statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileLang($expression)
{
return "<?php echo app('translator')->get$expression; ?>";
}
/**
* Compile the choice statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileChoice($expression)
{
return "<?php echo app('translator')->choice$expression; ?>";
}
/**
* Compile the else statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileElse($expression)
{
return '<?php else: ?>';
}
/**
* Compile the for statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileFor($expression)
{
return "<?php for{$expression}: ?>";
}
/**
* Compile the foreach statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileForeach($expression)
{
preg_match('/\( *(.*) +as *(.*)\)$/is', $expression, $matches);
$iteratee = trim($matches[1]);
$iteration = trim($matches[2]);
$initLoop = "\$__currentLoopData = {$iteratee}; \$__env->addLoop(\$__currentLoopData);";
$iterateLoop = '$__env->incrementLoopIndices(); $loop = $__env->getFirstLoop();';
return "<?php {$initLoop} foreach(\$__currentLoopData as {$iteration}): {$iterateLoop} ?>";
}
/**
* Compile the break statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileBreak($expression)
{
return $expression ? "<?php if{$expression} break; ?>" : '<?php break; ?>';
}
/**
* Compile the continue statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileContinue($expression)
{
return $expression ? "<?php if{$expression} continue; ?>" : '<?php continue; ?>';
}
/**
* Compile the forelse statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileForelse($expression)
{
$empty = '$__empty_'.++$this->forelseCounter;
preg_match('/\( *(.*) +as *(.*)\)$/is', $expression, $matches);
$iteratee = trim($matches[1]);
$iteration = trim($matches[2]);
$initLoop = "\$__currentLoopData = {$iteratee}; \$__env->addLoop(\$__currentLoopData);";
$iterateLoop = '$__env->incrementLoopIndices(); $loop = $__env->getFirstLoop();';
return "<?php {$empty} = true; {$initLoop} foreach(\$__currentLoopData as {$iteration}): {$iterateLoop} {$empty} = false; ?>";
}
/**
* Compile the can statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileCan($expression)
{
return "<?php if (app('Illuminate\\Contracts\\Auth\\Access\\Gate')->check{$expression}): ?>";
}
/**
* Compile the else-can statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileElsecan($expression)
{
return "<?php elseif (app('Illuminate\\Contracts\\Auth\\Access\\Gate')->check{$expression}): ?>";
}
/**
* Compile the cannot statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileCannot($expression)
{
return "<?php if (app('Illuminate\\Contracts\\Auth\\Access\\Gate')->denies{$expression}): ?>";
}
/**
* Compile the else-can statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileElsecannot($expression)
{
return "<?php elseif (app('Illuminate\\Contracts\\Auth\\Access\\Gate')->denies{$expression}): ?>";
}
/**
* Compile the if statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileIf($expression)
{
return "<?php if{$expression}: ?>";
}
/**
* Compile the else-if statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileElseif($expression)
{
return "<?php elseif{$expression}: ?>";
}
/**
* Compile the forelse statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEmpty($expression)
{
$empty = '$__empty_'.$this->forelseCounter--;
return "<?php endforeach; \$__env->popLoop(); \$loop = \$__env->getFirstLoop(); if ({$empty}): ?>";
}
/**
* Compile the has section statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileHasSection($expression)
{
return "<?php if (! empty(trim(\$__env->yieldContent{$expression}))): ?>";
}
/**
* Compile the while statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileWhile($expression)
{
return "<?php while{$expression}: ?>";
}
/**
* Compile the end-while statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndwhile($expression)
{
return '<?php endwhile; ?>';
}
/**
* Compile the end-for statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndfor($expression)
{
return '<?php endfor; ?>';
}
/**
* Compile the end-for-each statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndforeach($expression)
{
return '<?php endforeach; $__env->popLoop(); $loop = $__env->getFirstLoop(); ?>';
}
/**
* Compile the end-can statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndcan($expression)
{
return '<?php endif; ?>';
}
/**
* Compile the end-cannot statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndcannot($expression)
{
return '<?php endif; ?>';
}
/**
* Compile the end-if statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndif($expression)
{
return '<?php endif; ?>';
}
/**
* Compile the end-for-else statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndforelse($expression)
{
return '<?php endif; ?>';
}
/**
* Compile the raw PHP statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compilePhp($expression)
{
return $expression ? "<?php {$expression}; ?>" : '<?php ';
}
/**
* Compile end-php statement into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndphp($expression)
{
return ' ?>';
}
/**
* Compile the unset statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileUnset($expression)
{
return "<?php unset{$expression}; ?>";
}
/**
* Compile the extends statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileExtends($expression)
{
$expression = $this->stripParentheses($expression);
$data = "<?php echo \$__env->make($expression, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
$this->footer[] = $data;
return '';
}
/**
* Compile the include statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileInclude($expression)
{
$expression = $this->stripParentheses($expression);
return "<?php echo \$__env->make($expression, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
}
/**
* Compile the include statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileIncludeIf($expression)
{
$expression = $this->stripParentheses($expression);
return "<?php if (\$__env->exists($expression)) echo \$__env->make($expression, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
}
/**
* Compile the stack statements into the content.
*
* #param string $expression
* #return string
*/
protected function compileStack($expression)
{
return "<?php echo \$__env->yieldPushContent{$expression}; ?>";
}
/**
* Compile the push statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compilePush($expression)
{
return "<?php \$__env->startPush{$expression}; ?>";
}
/**
* Compile the endpush statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndpush($expression)
{
return '<?php $__env->stopPush(); ?>';
}
/**
* Strip the parentheses from the given expression.
*
* #param string $expression
* #return string
*/
public function stripParentheses($expression)
{
if (Str::startsWith($expression, '(')) {
$expression = substr($expression, 1, -1);
}
return $expression;
}
/**
* Get the extensions used by the compiler.
*
* #return array
*/
public function getExtensions()
{
return $this->extensions;
}
/**
* Register a custom Blade compiler.
*
* #param callable $compiler
* #return void
*/
public function extend(callable $compiler)
{
$this->extensions[] = $compiler;
}
/**
* Call the given directive with the given value.
*
* #param string $name
* #param string|null $value
* #return string
*/
protected function callCustomDirective($name, $value)
{
if (Str::startsWith($value, '(') && Str::endsWith($value, ')')) {
$value = Str::substr($value, 1, -1);
}
return call_user_func($this->customDirectives[$name], trim($value));
}
/**
* Register a handler for custom directives.
*
* #param string $name
* #param callable $handler
* #return void
*/
public function directive($name, callable $handler)
{
$this->customDirectives[$name] = $handler;
}
/**
* Get the list of custom directives.
*
* #return array
*/
public function getCustomDirectives()
{
return $this->customDirectives;
}
/**
* Gets the raw tags used by the compiler.
*
* #return array
*/
public function getRawTags()
{
return $this->rawTags;
}
/**
* Sets the raw tags used for the compiler.
*
* #param string $openTag
* #param string $closeTag
* #return void
*/
public function setRawTags($openTag, $closeTag)
{
$this->rawTags = [preg_quote($openTag), preg_quote($closeTag)];
}
/**
* Sets the content tags used for the compiler.
*
* #param string $openTag
* #param string $closeTag
* #param bool $escaped
* #return void
*/
public function setContentTags($openTag, $closeTag, $escaped = false)
{
$property = ($escaped === true) ? 'escapedTags' : 'contentTags';
$this->{$property} = [preg_quote($openTag), preg_quote($closeTag)];
}
/**
* Sets the escaped content tags used for the compiler.
*
* #param string $openTag
* #param string $closeTag
* #return void
*/
public function setEscapedContentTags($openTag, $closeTag)
{
$this->setContentTags($openTag, $closeTag, true);
}
/**
* Gets the content tags used for the compiler.
*
* #return string
*/
public function getContentTags()
{
return $this->getTags();
}
/**
* Gets the escaped content tags used for the compiler.
*
* #return string
*/
public function getEscapedContentTags()
{
return $this->getTags(true);
}
/**
* Gets the tags used for the compiler.
*
* #param bool $escaped
* #return array
*/
protected function getTags($escaped = false)
{
$tags = $escaped ? $this->escapedTags : $this->contentTags;
return array_map('stripcslashes', $tags);
}
/**
* Set the echo format to be used by the compiler.
*
* #param string $format
* #return void
*/
public function setEchoFormat($format)
{
$this->echoFormat = $format;
}
}
Then created provider
<?php
namespace App\Providers;
use App\Classes\Compiler\CustomCompiler;
use Illuminate\View\Engines\CompilerEngine;
use Illuminate\View\ViewServiceProvider as ViewProvider;
class ViewServiceProvider extends ViewProvider
{
public function registerBladeEngine($resolver)
{
$this->app->singleton('blade.compiler', function () {
return new CustomCompiler(
$this->app['files'], $this->app['config']['view.compiled']
);
});
$resolver->register('blade', function () {
return new CompilerEngine($this->app['blade.compiler']);
});
}
}
then replaced
Illuminate\View\ViewServiceProvider::class,
with my own
App\Providers\ViewServiceProvider::class,
in config/app.php.
Then put the .blade.php to the Non-PHP-encryption extensions.
I use obfuscation and generated key.
Blade templates work fine.
Consider that I got several models that store some flags using MySQL's bit field.
I know that it can easily be converted into bool by doing the follow:
$myBoolFlag = (ord($model->myFlag) == 1) ? true : false;
I'm looking for some way to make it map to a boolean property automatically.
Please someone tell me that there is an better way than creating setters and getters for every bit field in my project. I bet that Phalcon has some magic configuration in the DB service or something like this...
The way I have dealt with a similar issue is to create map arrays in each model and work with those. More specifically:
<?php
/**
* Model.php
*
* Model
*
* #author Nikos Dimopoulos <nikos#niden.net>
* #since 2012-12-12
* #category Library
*
*/
namespace NDN;
use \Phalcon\DI\FactoryDefault as PhDi;
use \Phalcon\Mvc\Model as PhModel;
class Model extends PhModel
{
private $meta = [];
/**
* Some init stuff
*/
public function initialize()
{
// Disable literals
$this->setup(['phqlLiterals' => false]);
}
/**
* Universal method caller. This checks the available methods based on
* the fields in the meta array and returns the relevant results
*
* #author Nikos Dimopoulos <nikos#niden.net>
* #since 2015-02-15
*
* #param string $function
* #param array|null $arguments
*
* #return mixed|void
* #throws \Exception
*/
public function __call($function, $arguments = null)
{
// $function is something like getId, setId, getName etc.
$metaFunction = substr($function, 3);
$field = $this->getMetaFunctionToField($metaFunction);
if ($field) {
$prefix = substr($function, 0, 3);
$fieldName = $field['field'];
switch ($prefix) {
case 'get':
/**
* Data manipulation here if needed
*/
$value = $this->getField($fieldName);
$value = $this->metaFieldValidate($field, $value);
return $value;
break;
case 'set':
/**
* Data manipulation here
*/
$value = $this->metaFieldValidate($field, $arguments);
$this->setField($field, $value);
break;
}
} else {
throw new \Exception('Function does not exist');
}
}
/**
* -------------------------------------------------------------------------
* PROTECTED METHODS
* -------------------------------------------------------------------------
*/
/**
* Gets a field from the model with the correct prefix
*
* #param $name
*
* #return mixed
*/
protected function getField($name)
{
return $this->$name;
}
/**
* Sets a field in the model
*
* #author Nikos Dimopoulos <nikos#niden.net>
* #since 2014-02-15
*
* #param string $field
* #param mixed $value
*/
protected function setField($field, $value)
{
$this->$field = $value;
}
/**
* Returns the DI container
*
* #author Nikos Dimopoulos <nikos#niden.net>
* #since 2014-02-22
*
* #return mixed
*/
public function getDI()
{
return PhDi::getDefault();
}
/**
* Accesses the internal array map to provide the field name from a function
*
* #author Nikos Dimopoulos <nikos#niden.net>
* #since 2014-02-27
*
* #param string $prefix The prefix of the table
* #param string $function The aliased function
*
* #return string The field name (i.e. tnt_id)
* bool False if not found
*/
public function getMetaFunctionToField($function)
{
if (array_key_exists($function, $this->meta)) {
return $this->meta[$function];
}
return false;
}
/**
* Validates a setter value based on each field's type
*
* #author Nikos Dimopoulos <nikos#niden.net>
* #since 2014-02-17
*
* #param string $field The field to check
* #param mixed $value The value of the field
*
* #return bool|int|string
*/
protected function metaFieldValidate($field, $value)
{
// Find the validator
$validator = $field['validator'];
switch ($validator)
{
case 'int':
$return = intval($value);
break;
case 'bit':
$return = (ord($value) == 1) ? true : false;
break;
case 'bool':
$return = (bool) $value;
break;
case 'decimal':
$return = (float) $value;
break;
case 'string':
$return = (string) $value;
break;
case 'datetime':
/**
* #todo check datetime validator
*/
$return = (string) $value;
break;
default:
$return = $value;
break;
}
return $return;
}
}
A sample User model looks like this
<?php
/**
* User.php
*
* User
*
* #author Nikos Dimopoulos <nikos#niden.net>
* #since 2014-03-08
* #category Models
*
*/
namespace NDN;
use \NDN\Model as NDNModel;
class Model extends NDNModel
{
public function initialize()
{
/**
* This is where I will set the field map
*
* The key of the array is the function name without
* the prefix. So for instance if you want getName()
* to return the user.name you use Name as the key
*/
$this->data = [
'Id' => [
'field' => 'user_id',
'validator' => 'int',
],
'Name' => [
'field' => 'user_name',
'validator' => 'int',
],
'IsMarried' => [
'field' => 'user_is_married',
'validator' => 'bit',
]
];
parent::initialize();
}
}
I've ended up by following the Nikolao's approach and implemented a base class for my models that can parse bit fields into more practical values. However, I designed it to not override the default mapping behavior. Something like that:
abstract class BaseModel extends Phalcon\Mvc\Model
{
public function explicitDataTypes()
{
//TODO: Suport relational data
$numargs = func_num_args();
if($numargs)
{
foreach (func_get_args() as $arg)
{
if(isset($this->$arg)) $this->$arg = $this->explicitDataType($arg)
}
}
else
{
foreach (get_object_vars($this) as $key => $value)
{
if($key[0] != '_') $this->$key = $this->explicitDataType($key)
}
}
}
public function explicitDataType($propertyName)
{
$value = $this->$propertyName;
if(is_numeric($value))
{
$locale = localeconv();
$separatorCount = substr_count($value, $locale['decimal_point']);
if($separatorCount == 0) $value = (int)$value;
elseif($separatorCount == 1) $value = (float)$value;
}
elseif(strlen($value) == 1 && ord($value) <= 1) $value = ord($value) == 1;
return $value;
}
}
Examples
class User extends BaseModel
{
protected $password;
public function afterFetch()
{
//Explicit data type for specific fields (e.g. var_dump($user->activated); //bool(true))
$this->explicitDataTypes('activated', 'deleted');
}
}
class Location extends BaseModel
{
public function afterFetch()
{
//Explicit data type for specific all fields (e.g. var_dump($location->distance); //float(12.3)
$this->explicitDataTypes();
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
WAMP Stack PHP “Fatal error: Class ‘SoapClient’ not found”
I downloaded a library from this site library and when I tried to use it's examples it says : "Fatal error: Class 'SoapClient' not found in C:\wamp\www\Amazon-ECS\Exeu-Amazon-ECS-PHP-Library-9030053\lib\AmazonECS.class.php on line 231" How should I able to fix this?
<?php
/**
* Amazon ECS Class
* http://www.amazon.com
* =====================
*
* This class fetchs productinformation via the Product Advertising API by Amazon (formerly ECS).
* It supports three basic operations: ItemSearch, ItemLookup and BrowseNodeLookup.
* These operations could be expanded with extra prarmeters to specialize the query.
*
* Requirement is the PHP extension SOAP.
*
* #package AmazonECS
* #license http://www.gnu.org/licenses/gpl.txt GPL
* #version 1.3.4-DEV
* #author Exeu <exeu65#googlemail.com>
* #contributor Julien Chaumond <chaumond#gmail.com>
* #link http://github.com/Exeu/Amazon-ECS-PHP-Library/wiki Wiki
* #link http://github.com/Exeu/Amazon-ECS-PHP-Library Source
*/
class AmazonECS
{
const RETURN_TYPE_ARRAY = 1;
const RETURN_TYPE_OBJECT = 2;
/**
* Baseconfigurationstorage
*
* #var array
*/
private $requestConfig = array(
'requestDelay' => false
);
/**
* Responseconfigurationstorage
*
* #var array
*/
private $responseConfig = array(
'returnType' => self::RETURN_TYPE_OBJECT,
'responseGroup' => 'Small',
'optionalParameters' => array()
);
/**
* All possible locations
*
* #var array
*/
private $possibleLocations = array('de', 'com', 'co.uk', 'ca', 'fr', 'co.jp', 'it', 'cn', 'es');
/**
* The WSDL File
*
* #var string
*/
protected $webserviceWsdl = 'http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl';
/**
* The SOAP Endpoint
*
* #var string
*/
protected $webserviceEndpoint = 'https://webservices.amazon.%%COUNTRY%%/onca/soap?Service=AWSECommerceService';
/**
* #param string $accessKey
* #param string $secretKey
* #param string $country
* #param string $associateTag
*/
public function __construct($accessKey, $secretKey, $country, $associateTag)
{
if (empty($accessKey) || empty($secretKey))
{
throw new Exception('No Access Key or Secret Key has been set');
}
$this->requestConfig['accessKey'] = $accessKey;
$this->requestConfig['secretKey'] = $secretKey;
$this->associateTag($associateTag);
$this->country($country);
}
/**
* execute search
*
* #param string $pattern
*
* #return array|object return type depends on setting
*
* #see returnType()
*/
public function search($pattern, $nodeId = null)
{
if (false === isset($this->requestConfig['category']))
{
throw new Exception('No Category given: Please set it up before');
}
$browseNode = array();
if (null !== $nodeId && true === $this->validateNodeId($nodeId))
{
$browseNode = array('BrowseNode' => $nodeId);
}
$params = $this->buildRequestParams('ItemSearch', array_merge(
array(
'Keywords' => $pattern,
'SearchIndex' => $this->requestConfig['category']
),
$browseNode
));
return $this->returnData(
$this->performSoapRequest("ItemSearch", $params)
);
}
/**
* execute ItemLookup request
*
* #param string $asin
*
* #return array|object return type depends on setting
*
* #see returnType()
*/
public function lookup($asin)
{
$params = $this->buildRequestParams('ItemLookup', array(
'ItemId' => $asin,
));
return $this->returnData(
$this->performSoapRequest("ItemLookup", $params)
);
}
/**
* Implementation of BrowseNodeLookup
* This allows to fetch information about nodes (children anchestors, etc.)
*
* #param integer $nodeId
*/
public function browseNodeLookup($nodeId)
{
$this->validateNodeId($nodeId);
$params = $this->buildRequestParams('BrowseNodeLookup', array(
'BrowseNodeId' => $nodeId
));
return $this->returnData(
$this->performSoapRequest("BrowseNodeLookup", $params)
);
}
/**
* Implementation of SimilarityLookup
* This allows to fetch information about product related to the parameter product
*
* #param string $asin
*/
public function similarityLookup($asin)
{
$params = $this->buildRequestParams('SimilarityLookup', array(
'ItemId' => $asin
));
return $this->returnData(
$this->performSoapRequest("SimilarityLookup", $params)
);
}
/**
* Builds the request parameters
*
* #param string $function
* #param array $params
*
* #return array
*/
protected function buildRequestParams($function, array $params)
{
$associateTag = array();
if(false === empty($this->requestConfig['associateTag']))
{
$associateTag = array('AssociateTag' => $this->requestConfig['associateTag']);
}
return array_merge(
$associateTag,
array(
'AWSAccessKeyId' => $this->requestConfig['accessKey'],
'Request' => array_merge(
array('Operation' => $function),
$params,
$this->responseConfig['optionalParameters'],
array('ResponseGroup' => $this->prepareResponseGroup())
)));
}
/**
* Prepares the responsegroups and returns them as array
*
* #return array|prepared responsegroups
*/
protected function prepareResponseGroup()
{
if (false === strstr($this->responseConfig['responseGroup'], ','))
return $this->responseConfig['responseGroup'];
return explode(',', $this->responseConfig['responseGroup']);
}
/**
* #param string $function Name of the function which should be called
* #param array $params Requestparameters 'ParameterName' => 'ParameterValue'
*
* #return array The response as an array with stdClass objects
*/
protected function performSoapRequest($function, $params)
{
if (true === $this->requestConfig['requestDelay']) {
sleep(1);
}
$soapClient = new SoapClient(
$this->webserviceWsdl,
array('exceptions' => 1)
);
$soapClient->__setLocation(str_replace(
'%%COUNTRY%%',
$this->responseConfig['country'],
$this->webserviceEndpoint
));
$soapClient->__setSoapHeaders($this->buildSoapHeader($function));
return $soapClient->__soapCall($function, array($params));
}
/**
* Provides some necessary soap headers
*
* #param string $function
*
* #return array Each element is a concrete SoapHeader object
*/
protected function buildSoapHeader($function)
{
$timeStamp = $this->getTimestamp();
$signature = $this->buildSignature($function . $timeStamp);
return array(
new SoapHeader(
'http://security.amazonaws.com/doc/2007-01-01/',
'AWSAccessKeyId',
$this->requestConfig['accessKey']
),
new SoapHeader(
'http://security.amazonaws.com/doc/2007-01-01/',
'Timestamp',
$timeStamp
),
new SoapHeader(
'http://security.amazonaws.com/doc/2007-01-01/',
'Signature',
$signature
)
);
}
/**
* provides current gm date
*
* primary needed for the signature
*
* #return string
*/
final protected function getTimestamp()
{
return gmdate("Y-m-d\TH:i:s\Z");
}
/**
* provides the signature
*
* #return string
*/
final protected function buildSignature($request)
{
return base64_encode(hash_hmac("sha256", $request, $this->requestConfig['secretKey'], true));
}
/**
* Basic validation of the nodeId
*
* #param integer $nodeId
*
* #return boolean
*/
final protected function validateNodeId($nodeId)
{
if (false === is_numeric($nodeId) || $nodeId <= 0)
{
throw new InvalidArgumentException(sprintf('Node has to be a positive Integer.'));
}
return true;
}
/**
* Returns the response either as Array or Array/Object
*
* #param object $object
*
* #return mixed
*/
protected function returnData($object)
{
switch ($this->responseConfig['returnType'])
{
case self::RETURN_TYPE_OBJECT:
return $object;
break;
case self::RETURN_TYPE_ARRAY:
return $this->objectToArray($object);
break;
default:
throw new InvalidArgumentException(sprintf(
"Unknwon return type %s", $this->responseConfig['returnType']
));
break;
}
}
/**
* Transforms the responseobject to an array
*
* #param object $object
*
* #return array An arrayrepresentation of the given object
*/
protected function objectToArray($object)
{
$out = array();
foreach ($object as $key => $value)
{
switch (true)
{
case is_object($value):
$out[$key] = $this->objectToArray($value);
break;
case is_array($value):
$out[$key] = $this->objectToArray($value);
break;
default:
$out[$key] = $value;
break;
}
}
return $out;
}
/**
* set or get optional parameters
*
* if the argument params is null it will reutrn the current parameters,
* otherwise it will set the params and return itself.
*
* #param array $params the optional parameters
*
* #return array|AmazonECS depends on params argument
*/
public function optionalParameters($params = null)
{
if (null === $params)
{
return $this->responseConfig['optionalParameters'];
}
if (false === is_array($params))
{
throw new InvalidArgumentException(sprintf(
"%s is no valid parameter: Use an array with Key => Value Pairs", $params
));
}
$this->responseConfig['optionalParameters'] = $params;
return $this;
}
/**
* Set or get the country
*
* if the country argument is null it will return the current
* country, otherwise it will set the country and return itself.
*
* #param string|null $country
*
* #return string|AmazonECS depends on country argument
*/
public function country($country = null)
{
if (null === $country)
{
return $this->responseConfig['country'];
}
if (false === in_array(strtolower($country), $this->possibleLocations))
{
throw new InvalidArgumentException(sprintf(
"Invalid Country-Code: %s! Possible Country-Codes: %s",
$country,
implode(', ', $this->possibleLocations)
));
}
$this->responseConfig['country'] = strtolower($country);
return $this;
}
/**
* Setting/Getting the amazon category
*
* #param string $category
*
* #return string|AmazonECS depends on category argument
*/
public function category($category = null)
{
if (null === $category)
{
return isset($this->requestConfig['category']) ? $this->requestConfig['category'] : null;
}
$this->requestConfig['category'] = $category;
return $this;
}
/**
* Setting/Getting the responsegroup
*
* #param string $responseGroup Comma separated groups
*
* #return string|AmazonECS depends on responseGroup argument
*/
public function responseGroup($responseGroup = null)
{
if (null === $responseGroup)
{
return $this->responseConfig['responseGroup'];
}
$this->responseConfig['responseGroup'] = $responseGroup;
return $this;
}
/**
* Setting/Getting the returntype
* It can be an object or an array
*
* #param integer $type Use the constants RETURN_TYPE_ARRAY or RETURN_TYPE_OBJECT
*
* #return integer|AmazonECS depends on type argument
*/
public function returnType($type = null)
{
if (null === $type)
{
return $this->responseConfig['returnType'];
}
$this->responseConfig['returnType'] = $type;
return $this;
}
/**
* Setter/Getter of the AssociateTag.
* This could be used for late bindings of this attribute
*
* #param string $associateTag
*
* #return string|AmazonECS depends on associateTag argument
*/
public function associateTag($associateTag = null)
{
if (null === $associateTag)
{
return $this->requestConfig['associateTag'];
}
$this->requestConfig['associateTag'] = $associateTag;
return $this;
}
/**
* #deprecated use returnType() instead
*/
public function setReturnType($type)
{
return $this->returnType($type);
}
/**
* Setting the resultpage to a specified value.
* Allows to browse resultsets which have more than one page.
*
* #param integer $page
*
* #return AmazonECS
*/
public function page($page)
{
if (false === is_numeric($page) || $page <= 0)
{
throw new InvalidArgumentException(sprintf(
'%s is an invalid page value. It has to be numeric and positive',
$page
));
}
$this->responseConfig['optionalParameters'] = array_merge(
$this->responseConfig['optionalParameters'],
array("ItemPage" => $page)
);
return $this;
}
/**
* Enables or disables the request delay.
* If it is enabled (true) every request is delayed one second to get rid of the api request limit.
*
* Reasons for this you can read on this site:
* https://affiliate-program.amazon.com/gp/advertising/api/detail/faq.html
*
* By default the requestdelay is disabled
*
* #param boolean $enable true = enabled, false = disabled
*
* #return boolean|AmazonECS depends on enable argument
*/
public function requestDelay($enable = null)
{
if (false === is_null($enable) && true === is_bool($enable))
{
$this->requestConfig['requestDelay'] = $enable;
return $this;
}
return $this->requestConfig['requestDelay'];
}
}
The error appears to be caused by the version of PHP that you have does not have the SOAP extension enabled.
To resolve this simply start wamp, click on the wamp system tray icon. Within this screen select PHP then PHP extensions. This will display a list of extensions. Ensure that php_soap is ticked.
If you intend to access soap servers that use HTTPs then you will also ensure php_openssl is ticked.
I had this code that I wrote last year and it returns RSS feeds for some term I enter:
<html>
<body>
<form name="form" action="search.php" method="get">
<input type="text" name="q" />
<input type="submit" name="Submit" value="Search" />
</form>
<?php
require_once "RSS.php";
// want to parse the $row[1] variable to get out words, make new string with a + instead of spaces
$college = "college";
$collegelen= strlen($college);
for($i = 0; $i < $collegelen; $i++){
if ($college{$i} == " ")
{$spaced = $spaced . "+";}
else
{$spaced = $spaced . $college{$i};}
}
echo("Yahoo! News RSS");
$rss_yahoo =& new XML_RSS("http://news.search.yahoo.com/news/rss?p=" . $spaced . "&ei=UTF-8&fl=0&x=wrt");
$rss_yahoo->parse();
foreach ($rss_yahoo->getItems() as $item) {
echo "<li>" . $item['title'] . "</li><br>";
//echo $item['pubDate'] ."<br>";
echo $item['description'] . "<br><br>\n"; }
//echo("Google RSS");
//$rss_google =& new XML_RSS("http://news.google.com/news?hl=en&ned=us&q=" . $spaced . "&ie=UTF-8&nolr=1&output=rss");
//$rss_google->parse();
//foreach ($rss_google->getItems() as $item) {
// echo "<li>" . $item['title'] . "</li><br>";
// echo $item['description'] . "<br><br>\n"; }
echo("Google RSS");
$rss_google =& new XML_RSS("http://news.google.com/news?hl=en&ned=us&q=" . $spaced . "&ie=UTF-8&nolr=1&output=rss");
$rss_google->parse();
foreach ($rss_google->getItems() as $item) {
echo "<li>" . $item['title'] . "</li><br>";
- Hide quoted text -
"<br><br>\n"; }
?>
</body>
</html>
RSS.php
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 fdm=marker:
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license#php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Martin Jansen <mj#php.net> |
// | |
// +----------------------------------------------------------------------+
//
// $Id: RSS.php,v 1.28 2006/09/14 08:40:05 clay Exp $
//
require_once 'Parser.php';
/**
* RSS parser class.
*
* This class is a parser for Resource Description Framework (RDF) Site
* Summary (RSS) documents. For more information on RSS see the
* website of the RSS working group (http://www.purl.org/rss/).
*
* #author Martin Jansen <mj#php.net>
* #version $Revision: 1.28 $
* #access public
*/
class XML_RSS extends XML_Parser
{
// {{{ properties
/**
* #var string
*/
var $insideTag = '';
/**
* #var array
*/
var $insideTagStack = array();
/**
* #var string
*/
var $activeTag = '';
/**
* #var array
*/
var $channel = array();
/**
* #var array
*/
var $items = array();
/**
* #var array
*/
var $item = array();
/**
* #var array
*/
var $image = array();
/**
* #var array
*/
var $textinput = array();
/**
* #var array
*/
var $textinputs = array();
/**
* #var array
*/
var $attribs;
/**
* #var array
*/
var $parentTags = array('CHANNEL', 'ITEM', 'IMAGE', 'TEXTINPUT');
/**
* #var array
*/
var $channelTags = array('TITLE', 'LINK', 'DESCRIPTION', 'IMAGE',
'ITEMS', 'TEXTINPUT', 'LANGUAGE', 'COPYRIGHT',
'MANAGINGEditor', 'WEBMASTER', 'PUBDATE', 'LASTBUILDDATE',
'CATEGORY', 'GENERATOR', 'DOCS', 'CLOUD', 'TTL',
'RATING');
/**
* #var array
*/
var $itemTags = array('TITLE', 'LINK', 'DESCRIPTION', 'PUBDATE', 'AUTHOR', 'CATEGORY',
'COMMENTS', 'ENCLOSURE', 'GUID', 'PUBDATE', 'SOURCE',
'CONTENT:ENCODED');
/**
* #var array
*/
var $imageTags = array('TITLE', 'URL', 'LINK', 'WIDTH', 'HEIGHT');
var $textinputTags = array('TITLE', 'DESCRIPTION', 'NAME', 'LINK');
/**
* List of allowed module tags
*
* Currently supported:
*
* Dublin Core Metadata
* blogChannel RSS module
* CreativeCommons
* Content
* Syndication
* Trackback
* GeoCoding
* Media
* iTunes
*
* #var array
*/
var $moduleTags = array('DC:TITLE', 'DC:CREATOR', 'DC:SUBJECT', 'DC:DESCRIPTION',
'DC:PUBLISHER', 'DC:CONTRIBUTOR', 'DC:DATE', 'DC:TYPE',
'DC:FORMAT', 'DC:IDENTIFIER', 'DC:SOURCE', 'DC:LANGUAGE',
'DC:RELATION', 'DC:COVERAGE', 'DC:RIGHTS',
'BLOGCHANNEL:BLOGROLL', 'BLOGCHANNEL:MYSUBSCRIPTIONS',
'BLOGCHANNEL:BLINK', 'BLOGCHANNEL:CHANGES',
'CREATIVECOMMONS:LICENSE', 'CC:LICENSE', 'CONTENT:ENCODED',
'SY:UPDATEPERIOD', 'SY:UPDATEFREQUENCY', 'SY:UPDATEBASE',
'TRACKBACK:PING', 'GEO:LAT', 'GEO:LONG',
'MEDIA:GROUP', 'MEDIA:CONTENT', 'MEDIA:ADULT',
'MEDIA:RATING', 'MEDIA:TITLE', 'MEDIA:DESCRIPTION',
'MEDIA:KEYWORDS', 'MEDIA:THUMBNAIL', 'MEDIA:CATEGORY',
'MEDIA:HASH', 'MEDIA:PLAYER', 'MEDIA:CREDIT',
'MEDIA:COPYRIGHT', 'MEDIA:TEXT', 'MEDIA:RESTRICTION',
'ITUNES:AUTHOR', 'ITUNES:BLOCK', 'ITUNES:CATEGORY',
'ITUNES:DURATION', 'ITUNES:EXPLICIT', 'ITUNES:IMAGE',
'ITUNES:KEYWORDS', 'ITUNES:NEW-FEED-URL', 'ITUNES:OWNER',
'ITUNES:PUBDATE', 'ITUNES:SUBTITLE', 'ITUNES:SUMMARY'
);
/**
* #var array
*/
var $last = array();
// }}}
// {{{ Constructor
/**
* Constructor
*
* #access public
* #param mixed File pointer, name of the RSS file, or an RSS string.
* #param string Source charset encoding, use null (default) to use
* default encoding (ISO-8859-1)
* #param string Target charset encoding, use null (default) to use
* default encoding (ISO-8859-1)
* #return void
*/
function XML_RSS($handle = '', $srcenc = null, $tgtenc = null)
{
if ($srcenc === null && $tgtenc === null) {
$this->XML_Parser();
} else {
$this->XML_Parser($srcenc, 'event', $tgtenc);
}
$this->setInput($handle);
if ($handle == '') {
$this->raiseError('No input passed.');
}
}
// }}}
// {{{ startHandler()
/**
* Start element handler for XML parser
*
* #access private
* #param object XML parser object
* #param string XML element
* #param array Attributes of XML tag
* #return void
*/
function startHandler($parser, $element, $attribs)
{
if (substr($element, 0, 4) == "RSS:") {
$element = substr($element, 4);
}
switch ($element) {
case 'CHANNEL':
case 'ITEM':
case 'IMAGE':
case 'TEXTINPUT':
$this->insideTag = $element;
array_push($this->insideTagStack, $element);
break;
case 'ENCLOSURE' :
$this->attribs = $attribs;
break;
default:
$this->activeTag = $element;
}
}
// }}}
// {{{ endHandler()
/**
* End element handler for XML parser
*
* If the end of <item>, <channel>, <image> or <textinput>
* is reached, this method updates the structure array
* $this->struct[] and adds the field "type" to this array,
* that defines the type of the current field.
*
* #access private
* #param object XML parser object
* #param string
* #return void
*/
function endHandler($parser, $element)
{
if (substr($element, 0, 4) == "RSS:") {
$element = substr($element, 4);
}
if ($element == $this->insideTag) {
array_pop($this->insideTagStack);
$this->insideTag = end($this->insideTagStack);
$this->struct[] = array_merge(array('type' => strtolower($element)),
$this->last);
}
if ($element == 'ITEM') {
$this->items[] = $this->item;
$this->item = '';
}
if ($element == 'IMAGE') {
$this->images[] = $this->image;
$this->image = '';
}
if ($element == 'TEXTINPUT') {
$this->textinputs = $this->textinput;
$this->textinput = '';
}
if ($element == 'ENCLOSURE') {
if (!isset($this->item['enclosures'])) {
$this->item['enclosures'] = array();
}
$this->item['enclosures'][] = array_change_key_case($this->attribs, CASE_LOWER);
$this->attribs = array();
}
$this->activeTag = '';
}
// }}}
// {{{ cdataHandler()
/**
* Handler for character data
*
* #access private
* #param object XML parser object
* #param string CDATA
* #return void
*/
function cdataHandler($parser, $cdata)
{
if (in_array($this->insideTag, $this->parentTags)) {
$tagName = strtolower($this->insideTag);
$var = $this->{$tagName . 'Tags'};
if (in_array($this->activeTag, $var) ||
in_array($this->activeTag, $this->moduleTags)) {
$this->_add($tagName, strtolower($this->activeTag),
$cdata);
}
}
}
// }}}
// {{{ defaultHandler()
/**
* Default handler for XML parser
*
* #access private
* #param object XML parser object
* #param string CDATA
* #return void
*/
function defaultHandler($parser, $cdata)
{
return;
}
// }}}
// {{{ _add()
/**
* Add element to internal result sets
*
* #access private
* #param string Name of the result set
* #param string Fieldname
* #param string Value
* #return void
* #see cdataHandler
*/
function _add($type, $field, $value)
{
if (empty($this->{$type}) || empty($this->{$type}[$field])) {
$this->{$type}[$field] = $value;
} else {
$this->{$type}[$field] .= $value;
}
$this->last = $this->{$type};
}
// }}}
// {{{ getStructure()
/**
* Get complete structure of RSS file
*
* #access public
* #return array
*/
function getStructure()
{
return (array)$this->struct;
}
// }}}
// {{{ getchannelInfo()
/**
* Get general information about current channel
*
* This method returns an array containing the information
* that has been extracted from the <channel>-tag while parsing
* the RSS file.
*
* #access public
* #return array
*/
function getChannelInfo()
{
return (array)$this->channel;
}
// }}}
// {{{ getItems()
/**
* Get items from RSS file
*
* This method returns an array containing the set of items
* that are provided by the RSS file.
*
* #access public
* #return array
*/
function getItems()
{
return (array)$this->items;
}
// }}}
// {{{ getImages()
/**
* Get images from RSS file
*
* This method returns an array containing the set of images
* that are provided by the RSS file.
*
* #access public
* #return array
*/
function getImages()
{
return (array)$this->images;
}
// }}}
// {{{ getTextinputs()
/**
* Get text input fields from RSS file
*
* #access public
* #return array
*/
function getTextinputs()
{
return (array)$this->textinputs;
}
// }}}
}
?>
However, this code doesn't work anymore or I am not testing it correctly...I am running it on xampp on mac.
I wanted to make something like this:
The user enters a term and I want to display the RSS feeds from Yahoo, Google or NYTimes.
Thanks!
EDIT: I got two files RSS.php and Parser.php from a site last year and now it looks like the site is down. I am trying to see if anyone can offer another solution. Thanks!
Maybe you could try SimplePie. It's easy to use and have active development. You can start using right away, or reading the documentation for more advance usage.