Call to undefined method Config::getConfig() - php

I'm testing the Flexpaper plugin on Windows XP running with XAMP, the issue is that it doesn't shows the pdf's, checking the php error log it says:
PHP Fatal error: Call to undefined method Config::getConfig() in
C:\xampp\htdocs\PDFViewer\php\services\view.php on line 24
The folder structure is: (omitting irrelevant files)
htdocs/
|->PDFViewer/
|->php/
|->admin_files/
|->config/
|->config.ini.win.php
|->lib/
|->common.php
|->pdf2json_php5.php
|->pdf2swf_php5.php
|->config.php
|->services/
|->view.php
Snippet of code of view.php
require_once("../lib/common.php");
require_once("../lib/pdf2swf_php5.php");
require_once("../lib/swfrender_php5.php");
require_once("../lib/pdf2json_php5.php");
Snippet of code of pdf2json_php5.php
require_once("config.php");
require_once("common.php");
Snippet of code of pdf2swf_php5.php
require_once("config.php");
require_once("common.php");
Snippet of code of swfrender_php5.php
require_once("config.php");
require_once("common.php");
And before you ask, yes, config.php do have the getConfig method
Edit: Added the config.php
<?php date_default_timezone_set('America/New_York'); ?>
<?php
class Config{
protected $config;
public function __construct()
{
if (!defined('ROOT')) {
define('ROOT', dirname(dirname(dirname(__FILE__))));
}
if (!defined('APP_DIR')) {
define('APP_DIR', basename(dirname(dirname(__FILE__))));
}
if( PHP_OS == "WIN32" || PHP_OS == "WINNT" )
$this->config = parse_ini_file($this->getConfigFilename());
else
$this->config = parse_ini_file($this->getConfigFilename());
}
public function getConfigDir(){
if( PHP_OS == "WIN32" || PHP_OS == "WINNT" )
return dirname(__FILE__) . '\\..\\config';
else
return dirname(__FILE__) . '/../config';
}
public function getConfigs(){
return $this->config;
}
public function getConfig($key = null)
{
if($key !== null)
{
if(isset($this->config[$key]))
{
return $this->config[$key];
}
else
{
return null;
}
}
else
{
return $this->config;
}
}
public function setConfig($config)
{
$this->config = $config;
}
public function getDocUrl(){
return "<br/><br/>Click <a href='http://flexpaper.devaldi.com/docs_php.jsp'>here</a> for more information on configuring FlexPaper with PHP";
}
public function getConfigFilename(){
if( PHP_OS == "WIN32" || PHP_OS == "WINNT" )
return ROOT . '\\' . APP_DIR . '\\config\\config.ini.win.php';
else
return ROOT . '/' . APP_DIR . '/config/config.ini.nix.php';
}
public function saveConfig($array){
$this->write_php_ini($array,$this->getConfigFilename());
}
function write_php_ini($array, $file)
{
$res = array();
foreach($array as $key => $val)
{
if(is_array($val))
{
$res[] = "[$key]";
foreach($val as $skey => $sval) {
$sval = str_replace("\"","\\\"",$sval);
$res[] = "$skey = ".(is_numeric($sval) ? $sval : '"'.$sval.'"');
}
}
else {
$val = str_replace("\"","\\\"",$val);
$res[] = "$key = ".(is_numeric($val) ? $val : '"'.$val.'"');
}
}
$this->safefilerewrite($file, implode("\r\n", $res));
}
function safefilerewrite($fileName, $dataToSave)
{
$dataToSave = "; <?php exit; ?> DO NOT REMOVE THIS LINE\r\n" . $dataToSave;
if ($fp = fopen($fileName, 'w'))
{
$startTime = microtime();
do
{
$canWrite = flock($fp, LOCK_EX);
// If lock not obtained sleep for 0 - 100 milliseconds, to avoid collision and CPU load
if(!$canWrite) usleep(round(rand(0, 100)*1000));
} while ((!$canWrite)and((microtime()-$startTime) < 1000));
//file was locked so now we can store information
if ($canWrite)
{ fwrite($fp, $dataToSave);
flock($fp, LOCK_UN);
}
fclose($fp);
}else{
throw new Exception('Cant write to config ' . $fileName);
}
}
}

Modify the code snippet of view.php into:
$ds = DIRECTORY_SEPARATOR;
require_once("..{$ds}lib{$ds}common.php");
require_once("..{$ds}lib{$ds}pdf2swf_php5.php");
require_once("..{$ds}lib{$ds}swfrender_php5.php");
require_once("..{$ds}lib{$ds}pdf2json_php5.php");

Looks like I've made it work after adding C:/xampp/htdocs to the include_path variable in php.ini, and then just modified the require_once functions.
require_once section in View.php looks like:
require_once("PDFViewer/php/lib/common.php");
require_once("PDFViewer/php/lib/pdf2swf_php5.php");
require_once("PDFViewer/php/lib/swfrender_php5.php");
require_once("PDFViewer/php/lib/pdf2json_php5.php");
And the same for pdf2swf_php5.php, swfrender_php5.php and pdf2json_php5.php.

Related

How to properly rewrite php code from version 5.6 to 7.x?

I tied it myself but it does not work for me. How to properly change for example this old code to be compatible with php 7.x?
class DbSimple_Generic
{
function& connect($dsn)
{
// Load database driver and create its instance.
$parsed = DbSimple_Generic::parseDSN($dsn);
if (!$parsed) {
$dummy = null;
return $dummy;
}
$class = 'DbSimple_'.ucfirst($parsed['scheme']);
if (!class_exists($class)) {
$file = str_replace('_', '/', $class) . ".php";
if ($f = #fopen($file, "r", true)) {
fclose($f);
require_once($file);
} else {
$base = basename($file);
$dir = dirname(__FILE__);
if (#is_file($path = "$dir/$base")) {
require_once($path);
} else {
trigger_error("Error loading database driver: no file $file in include_path; no file $base in $dir", E_USER_ERROR);
return null;
}
}
}
$object =& new $class($parsed);
if (isset($parsed['ident_prefix'])) {
$object->setIdentPrefix($parsed['ident_prefix']);
}
class DbSimple_Mysql_Blob extends DbSimple_Generic_Blob
{
var $blobdata = null;
var $curSeek = 0;
function DbSimple_Mysql_Blob(&$database, $blobdata=null)
{
$this->blobdata = $blobdata;
$this->curSeek = 0;
}
function read($len)
{
$p = $this->curSeek;
$this->curSeek = min($this->curSeek + $len, strlen($this->blobdata));
return substr($this->blobdata, $this->curSeek, $len);
}
function write($data)
{
$this->blobdata .= $data;
}
function close()
{
return $this->blobdata;
}
function length()
{
return strlen($this->blobdata);
}
}
function& _performNewBlob($blobid=null)
{
$obj =& new DbSimple_Mysql_Blob($this, $blobid);
return $obj;
}
I tried to use every possible way to make this work like this:
$object = new $class($parsed);
$object->method();
Becase it seems for PHP 7.x is this the most problematic part:
$object =& new $class($parsed);
But thisdid not work. I tried to find it on some PHP documentation but no luck so far. So how to properly rewrite this? Thank you
Using this on Ubuntu Server 64bit 16.04+ with Apache and mysql.
Probably it is a better idea to understand that function and rewrite in a cleaner way but please find below my changes, hopefully it helps.
class DbSimple_Generic
{
function connect($dsn)
{
// Load database driver and create its instance.
$parsed = DbSimple_Generic::parseDSN($dsn);
if (!$parsed) {
$dummy = null;
return $dummy;
}
$class = 'DbSimple_'.ucfirst($parsed['scheme']);
if (!class_exists($class)) {
$file = str_replace('_', '/', $class) . ".php";
if ($f = #fopen($file, "r", true)) {
fclose($f);
require_once($file);
} else {
$base = basename($file);
$dir = dirname(__FILE__);
if (#is_file($path = "$dir/$base")) {
require_once($path);
} else {
trigger_error("Error loading database driver: no file $file in include_path; no file $base in $dir", E_USER_ERROR);
return null;
}
}
}
$object = new $class($parsed);
if (isset($parsed['ident_prefix'])) {
$object->setIdentPrefix($parsed['ident_prefix']);
}
}
public static function parseDSN($dsn){ // public or private depends on what you intend to do
// implementation here...
}
public function setIdentPrefix($identPrefix){
// implementation here...
}
}
class DbSimple_Mysql_Blob extends DbSimple_Generic_Blob
{
var $blobdata = null;
var $curSeek = 0;
function __construct($blobdata=null) // use __construct for class constructor
{
$this->blobdata = $blobdata;
$this->curSeek = 0;
}
function read($len)
{
$p = $this->curSeek;
$this->curSeek = min($this->curSeek + $len, strlen($this->blobdata));
return substr($this->blobdata, $this->curSeek, $len);
}
function write($data)
{
$this->blobdata .= $data;
}
function close()
{
return $this->blobdata;
}
function length()
{
return strlen($this->blobdata);
}
}
function _performNewBlob($blobid=null)
{
$obj = new DbSimple_Mysql_Blob($blobid); // no need to use &
return $obj;
}
Just don't ever use =& operator. It's been useless since PHP 5.0 and removed in PHP 7.0:
http://php.net/manual/en/migration70.incompatible.php#migration70.incompatible.other.new-by-ref
You will find more things on that page that no longer work in PHP 7.

How to make custom 404 page in routing system

I want to make a 404 error page on this routing. How can this be done?
index.php
<?php
include 'route.php';
include 'control/about.php';
include 'control/home.php';
include 'control/contact.php';
$route = new route();
$route->add('/', function(){
echo 'Hello, this is home pageeees';
});
$route->add('/about', 'about');
$route->add('/contact', 'contact');
echo '<pre>';
print_r($route);
$route->submit();
?>
route.php
<?php
class route
{
private $_uri = array();
private $_method = array();
/**
*Builds a collection of internal URL's to look for
*#parameter type $uri
*/
public function add($uri, $method = null)
{
$this->_uri[] = '/' . trim($uri, '/');
if($method != null){
$this->_method[] = $method;
}
}
/**
*Makes the thing run!
*/
public function submit()
{
$uriGetParam = isset($_GET['uri'])? '/' . $_GET['uri'] : '/';
foreach ($this->_uri as $key => $value)
{
if(preg_match("#^$value$#",$uriGetParam))
{
if(is_string($this->_method[$key]))
{
$useMethod = $this->_method[$key];
new $useMethod();
}
else
{
call_user_func($this->_method[$key]);
}
}
}
}
}
?>
The regex in mind I would just add $route->add("/.+", function()...); after all your other routes.
Proof: https://3v4l.org/nk5PZ
But you could also program some logic which evaluates custom 404-Pages when not being able to find a correspondig route.
For example:
private $_notFound;
public function submit() {
$uriGetParam = isset($_GET['uri'])? '/' . $_GET['uri'] : '/';
$matched = false;
foreach ($this->_uri as $key => $value) {
if(preg_match("#^$value$#", $uriGetParam)) {
if(is_string($this->_method[$key])) {
$useMethod = $this->_method[$key];
new $useMethod();
} else {
call_user_func($this->_method[$key]);
}
$matched = true;
}
}
if(!$matched) {
if(isset($this->_notFound)) {
if(is_string($this->_notFound)) {
$action = $this->_notFound;
new $action();
} else {
call_user_func($this->_notFound);
}
}
}
}
public function notFound($callback) {
$this->_notFound = $callback;
}
Then you'll have to add the 404-action by $route->notFound(function... or "class");

parse_ini_file data is always 1

I try to parse a ini file to load PHP classes from it but whenever parse_ini_file parses the file, the variable that holds the content is always only "1".
Here is my code:
private $plugins = array();
public function __construct() {
Logger::log("Loading plugins");
Logger::debug("Loading " . APP_ROOT . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "plugins.ini");
if (file_exists(APP_ROOT . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "plugins.ini")) {
$data = parse_ini_file(APP_ROOT . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "plugins.ini", true);
foreach ($data as $k => $d) {
if (class_exists($k)) {
$plugin = $this->createPlugin($k);
if ($plugin instanceof Plugin) {
$this->init($plugin, $d);
} else {
Logger::error("Plugin doesn't implements interface Plugin");
}
} else {
Logger::error("Can't load plugin $k");
}
}
} else {
Logger::error(APP_ROOT . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "plugins.ini doesn't exists");
}
}
public function createPlugin($name) {
$plugin = unserialize(
sprintf(
'O:%d:"%s":0:{}', strlen($name), $name
)
);
return $plugin;
}
public function init(Plugin $plugin, $data) {
try {
Logger::log("Adding plugin " . get_class($plugin));
Logger::debug("Calling init");
$plugin->init($data);
$this->plugins[get_class($plugin)] = $plugin;
} catch (PluginException $ex) {
Logger::error("Error while init plugin");
}
}
The ini file:
[\eBot\Plugins\Official\MissionChecker]
url=http://someurl
I tried to add a log message after
foreach ($data as $k => $d) {
But this line was never called, therefore $data must be empty, buw how is that possible?
var_dump and print_r($data) show me "1".
I solved the problem by putting the url in the ini file in quotes.
[\eBot\Plugins\Official\MissionChecker]
url="http://someurl"

Detecting use of register globals

Is there any way in PHP to do static code analysis and detect reliance on the register_globals initiative? It's relatively straightforward to manually examine a file and look for variables which have not been initialized and infer from that that these may be relying on it, but I need to do this for many hundreds of scripts, so I'm looking for an automated solution.
My last resort is setting up a dev environment with the directive turned off and strict error reporting and letting QA play around for a long while, then fix the instances that the error log catches, but this is not guaranteed to find 100% of the cases, and certainly not a good use of resources if an automated solution exists.
A small script I just hacked together to detect simple undefined variables. You'll need PHP-Parser for this:
<?php
error_reporting(E_ALL);
$dir = './foo';
require_once './lib/bootstrap.php';
class Scope {
protected $stack;
protected $pos;
public function __construct() {
$this->stack = array();
$this->pos = -1;
}
public function addVar($name) {
$this->stack[$this->pos][$name] = true;
}
public function hasVar($name) {
return isset($this->stack[$this->pos][$name]);
}
public function pushScope() {
$this->stack[++$this->pos] = array();
}
public function popScope() {
--$this->pos;
}
}
class UndefinedVariableVisitor extends PHPParser_NodeVisitorAbstract {
protected $scope;
protected $parser;
protected $traverser;
public function __construct(Scope $scope, PHPParser_Parser $parser, PHPParser_NodeTraverser $traverser) {
$this->scope = $scope;
$this->parser = $parser;
$this->traverser = $traverser;
}
public function enterNode(PHPParser_Node $node) {
if (($node instanceof PHPParser_Node_Expr_Assign || $node instanceof PHPParser_Node_Expr_AssignRef)
&& $node->var instanceof PHPParser_Node_Expr_Variable
&& is_string($node->var->name)
) {
$this->scope->addVar($node->var->name);
} elseif ($node instanceof PHPParser_Node_Stmt_Global || $node instanceof PHPParser_Node_Stmt_Static) {
foreach ($node->vars as $var) {
if (is_string($var->name)) {
$this->scope->addVar($var->name);
}
}
} elseif ($node instanceof PHPParser_Node_Expr_Variable && is_string($node->name)) {
if (!$this->scope->hasVar($node->name)) {
echo 'Undefined variable $' . $node->name . ' on line ' . $node->getLine() . "\n";
}
} elseif ($node instanceof PHPParser_Node_Stmt_Function || $node instanceof PHPParser_Node_Stmt_ClassMethod) {
$this->scope->pushScope();
// params are always available
foreach ($node->params as $param) {
$this->scope->addVar($param->name);
}
// methods always have $this
if ($node instanceof PHPParser_Node_Stmt_ClassMethod) {
$this->scope->addVar('this');
}
} elseif ($node instanceof PHPParser_Node_Expr_Include && $node->expr instanceof PHPParser_Node_Scalar_String) {
$file = $node->expr->value;
$code = file_get_contents($file);
$stmts = $this->parser->parse($code);
// for includes within the file
$cwd = getcwd();
chdir(dirname($file));
$this->traverser->traverse($stmts);
chdir($cwd);
}
}
public function leaveNode(PHPParser_Node $node) {
if ($node instanceof PHPParser_Node_Stmt_Function || $node instanceof PHPParser_Node_Stmt_ClassMethod) {
$this->scope->popScope();
}
}
}
$parser = new PHPParser_Parser(new PHPParser_Lexer());
$scope = new Scope;
$traverser = new PHPParser_NodeTraverser;
$traverser->addVisitor(new UndefinedVariableVisitor($scope, $parser, $traverser));
foreach (new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir),
RecursiveIteratorIterator::LEAVES_ONLY)
as $file
) {
if (!preg_match('/\.php$/', $file)) continue;
echo 'Checking ' . $file . ':', "\n";
$code = file_get_contents($file);
$stmts = $parser->parse($code);
// for includes within the file
$cwd = getcwd();
chdir(dirname($file));
$scope->pushScope();
$traverser->traverse($stmts);
$scope->popScope();
chdir($cwd);
echo "\n";
}
It's just a very basic implementation and I did not test it extensively, but it should work for scripts that don't go wild with $GLOBALS and $$varVars. It does basic include resolution.
This should work (from one of the php manual comments):
if (ini_get('register_globals')) {
foreach ($GLOBALS as $int_temp_name => $int_temp_value) {
if (!in_array($int_temp_name, array (
'GLOBALS',
'_FILES',
'_REQUEST',
'_COOKIE',
'_SERVER',
'_ENV',
'_SESSION',
ini_get('session.name'),
'int_temp_name',
'int_temp_value'
))) {
unset ($GLOBALS[$int_temp_name]);
}
}
}
Tweaked the code above with the latest parser: used it to make 5.4 register_globals to 7.2
<?php
/*
* pgParser.php is a "Abstract syntax tree" progam based on the Nikic PHP-Parser https://github.com/nikic/PHP-Parser
* Tweaked for use to lose register global variables.
*/
use PhpParser\Node;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitorAbstract;
use PhpParser\Parser;
error_reporting(E_ALL);
/*
* $dir contains a base dir to use when no PARAM directory eq "php ./pgParser.php /home/hrobben/php/ > results.txt"
*/
$dir = '/home/hrobben/php/';
/*
* $nonecheck : variables not to check....
* e.g ['GLOBALS','_COOKIE', 'properties'] -> $GLOBALS, $_COOKIE, $properties >>>>> will not been checked.
*/
$nonecheck = ['_COOKIE', '_SERVER', '_SESSION'];
/*
* if those names part or directory not include...
* this can be usefull when certain users (developers) have own directories
* empty = [] no directories will be excluded
* e.g. ['george', 'henry'] all directories /tree/git/base/src/henry/ and /template/george/blog/ will be excluded.
*/
$nonesubdir = ['henry', 'ckeditor'];
/*
* $excludeMatch can be filled with text in directory plus file to exclude.
* e.q. _MA. will exclude the file index_MA.php3 to scan.
* e.g. _MA will exclude the file /git/src/test_MAIN/index.php3
* be carefull.
* Not for include files, only base files.
*/
$excludeMatch = ['_HR.', '_ed.'];
/*
* you can give a base directory to begin scanning.
*/
if (count($argv) > 0) {
$dir = $argv[1];
}
require_once './vendor/autoload.php';
class Scope
{
protected $stack;
protected $pos;
public function __construct()
{
$this->stack = array();
$this->pos = -1;
}
public function addVar($name)
{
$this->stack[$this->pos][$name] = true;
}
public function hasVar($name): bool
{
return isset($this->stack[$this->pos][$name]);
}
public function pushScope()
{
$this->stack[++$this->pos] = array();
}
public function popScope()
{
--$this->pos;
}
public function getPos()
{
return $this->pos;
}
}
class UndefinedVariableVisitor extends NodeVisitorAbstract
{
protected $scope;
protected $parser;
protected $traverser;
protected $nonecheck;
protected $isInclude = false;
public function __construct(Scope $scope, Parser $parser, NodeTraverser $traverser, array $nonecheck)
{
$this->scope = $scope;
$this->parser = $parser;
$this->traverser = $traverser;
$this->nonecheck = $nonecheck;
}
public function enterNode(Node $node)
{
$includePath = ['/home/hrobben/php/include/class/'];
$nonesubdir = ['jp', 'jp117']; // for the include exclusion directories.
if (($node instanceof PhpParser\Node\Expr\Assign || $node instanceof PhpParser\Node\Expr\AssignRef)
&& $node->var instanceof PhpParser\Node\Expr\Variable
&& is_string($node->var->name)
) {
// if preg_replace uses the same var name as second argument, its not setting a var, it must also be on the first level.
if ($node->expr->name->parts[0] == 'preg_replace' && $node->expr->args[2]->value->name == $node->var->name && $this->scope->getPos() == 0) {
//echo 'found $'.$node->expr->args[2]->value->name.' level '.$this->scope->getPos()."\n";
} else {
//echo 'add var $' . $node->var->name . "\n";
$this->scope->addVar($node->var->name);
}
} elseif ($node instanceof PhpParser\Node\Stmt\Global_ || $node instanceof PhpParser\Node\Stmt\Static_) {
foreach ($node->vars as $var) {
if (is_string($var->name)) {
$this->scope->addVar($var->name);
//echo 'add global or static var $' . $var->name . "\n";
}
}
} elseif ($node instanceof PhpParser\Node\Stmt\Foreach_) {
$this->scope->addVar($node->valueVar->name);
if ($node->keyVar) {
$this->scope->addVar($node->keyVar->name);
}
} elseif ($node instanceof PhpParser\Node\Stmt\StaticVar) {
$this->scope->addVar($node->var->name);
} elseif ($node instanceof PhpParser\Node\Expr\FuncCall && ($node->name->parts[0] == 'preg_match')) {
foreach ($node->args as $args) {
if ($node->args[2]) {
$this->scope->addVar($node->args[2]->value->name);
}
}
} elseif ($node instanceof PhpParser\Node\Expr\List_) {
foreach ($node->items as $item) {
$this->scope->addVar($item->value->name);
}
} elseif ($node instanceof PhpParser\Node\Expr\Closure) {
foreach ($node->params as $param) {
$this->scope->addVar($param->var->name);
}
} elseif ($node instanceof PhpParser\Node\Expr\Variable && is_string($node->name) && !$node instanceof PhpParser\Node\Const_) {
if (!$this->scope->hasVar($node->name) && !in_array($node->name, $this->nonecheck)) {
echo 'Undefined variable $' . $node->name . ' on line ' . $node->getLine() . "\n";
}
} elseif ($node instanceof PhpParser\Node\Stmt\Function_ || $node instanceof PhpParser\Node\Stmt\ClassMethod) {
$this->scope->pushScope();
// params are always available
foreach ($node->params as $param) {
//echo 'param name : '. $param->var->name. "\n";
$this->scope->addVar($param->var->name);
}
// methods always have $this
if ($node instanceof PhpParser\Node\Stmt\ClassMethod) {
$this->scope->addVar('this');
}
} elseif ($node instanceof PhpParser\Node\Expr\Include_ && $node->expr instanceof PhpParser\Node\Scalar\String_) {
$file = $node->expr->value;
$code = file_get_contents($file);
if (strlen($code) < 5) {
foreach ($includePath as $path) {
if (strlen($code) < 5) {
$code = file_get_contents($path . $file);
}
}
}
$match_string = implode("\/|", $nonesubdir);
if (preg_match("/$match_string\//", $file)) {
$code = '';
echo 'file skipped: ' . $file . "\n";
}
$stmts = $this->parser->parse($code);
// for includes within the file
$cwd = getcwd();
chdir(dirname($file));
$this->isInclude = true;
$this->traverser->traverse($stmts);
$this->isInclude = false;
chdir($cwd);
if (strlen($code) < 5) {
echo 'Include <- ' . $file . ' not found or empty.' . "\n";
} else {
echo 'Include <- ' . $file . "\n";
}
}
}
public function leaveNode(Node $node)
{
if ($node instanceof PhpParser\Node\Stmt\Function_ || $node instanceof PhpParser\Node\Stmt\ClassMethod) {
$this->scope->popScope();
}
}
}
$lexer = new PhpParser\Lexer();
$parser = (new PhpParser\ParserFactory)->create(
PhpParser\ParserFactory::PREFER_PHP7,
$lexer
);
$scope = new Scope;
$traverser = new NodeTraverser();
$traverser->addVisitor(new UndefinedVariableVisitor($scope, $parser, $traverser, $nonecheck));
foreach (new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir),
RecursiveIteratorIterator::LEAVES_ONLY)
as $file
) {
if (!preg_match('/\.php$|\.html$|\.php3$/', $file)) continue;
$match_string = implode("\/|\/", $nonesubdir);
if (preg_match("/\/$match_string\//", $file)) continue;
$match_string = implode("|", $excludeMatch);
if (preg_match("/$match_string/", $file)) continue;
echo 'Checking ' . $file . ':', "\n";
$code = file_get_contents($file);
$stmts = $parser->parse($code);
// print_r($stmts);
// for includes within the file
$cwd = getcwd();
chdir(dirname($file));
$scope->pushScope();
$traverser->traverse($stmts);
//print_r($stmts);
$scope->popScope();
chdir($cwd);
echo "\n";
}
Used this to make a big many script files holding code to go without global registered variables. We gone use it with PHP7.2

Is using Controller::render() in a Model::afterSave() possible with CakePHP?

I've got some sample code that I'd like to refactor as I need it to work after a record is saved. It currently works after the record is first rendered (using the afterFilter). What it does is render the view that I want with the layout and saves it to a file.
function afterFilter() {
parent::afterFilter();
if($this->params['pass'][0] == 'contact') {
$surrenderOuput = $this->surrender($this->params['pass'][0]);
$path = WWW_ROOT . 'cache' . DS . $this->params['pass'][0] . DS . 'index.html';
$file = new File($path, true);
$file->write($surrenderOuput);
$file->close();
}
}
function surrender($action = null, $layout = null, $file = null) {
$this->beforeRender();
$viewClass = $this->view;
if ($this->view != 'View') {
if (strpos($viewClass, '.') !== false) {
list($plugin, $viewClass) = explode('.', $viewClass);
}
$viewClass = $viewClass . 'View';
App::import('View', $this->view);
}
$this->Component->beforeRender($this);
$this->params['models'] = $this->modelNames;
if (Configure::read() > 2) {
$this->set('cakeDebug', $this);
}
$View =& new $viewClass($this);
if (!empty($this->modelNames)) {
$models = array();
foreach ($this->modelNames as $currentModel) {
if (isset($this->$currentModel) && is_a($this->$currentModel, 'Model')) {
$models[] = Inflector::underscore($currentModel);
}
$isValidModel = (
isset($this->$currentModel) && is_a($this->$currentModel, 'Model') &&
!empty($this->$currentModel->validationErrors)
);
if ($isValidModel) {
$View->validationErrors[Inflector::camelize($currentModel)] =&
$this->$currentModel->validationErrors;
}
}
$models = array_diff(ClassRegistry::keys(), $models);
foreach ($models as $currentModel) {
if (ClassRegistry::isKeySet($currentModel)) {
$currentObject =& ClassRegistry::getObject($currentModel);
if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) {
$View->validationErrors[Inflector::camelize($currentModel)] =&
$currentObject->validationErrors;
}
}
}
}
$this->autoRender = false;
$output = $View->render($action, $layout, $file);
return $output;
}
So I'm basically rendering the view with it's layout, and returning it as output, and saving it to a file. Great. Is there any way to do something similar in a model?
You may consider setting a member variable in your afterSave() in the model and checking that value in your afterFilter() in your controller.
I found this thread while searching for how to render a view from a model. In my case I'm calling a custom method in the model, so this might not work for afterSave(), but if you're calling a custom method you can do it like this:
Controller:
$this->Model->myFunc($this);
Model
public function myFunc($object) {
$object->render();
}
Hopefully that helps someone else who comes across this thread.

Categories