How to add auto complete to classes instantiated with custom function? - php

I instantiate my classes through custom functions.
The classes are in app/code/core/ e.g.
app/code/core/Property/Helper/Property.php
require_once("Core/Helper.php");
class Property_Helper_Property extends Core\Helper
{
public function __construct($con)
{
parent::__construct($con);
}
public function test()
{
return "hello";
}
}
app/code/core/Core/Helper.php
<?php
namespace Core;
abstract class Helper
{
protected $con;
public function __construct($con)
{
$this->con = $con;
}
}
I can call the method test() of the class Property_Helper_Property from any file like this:
require_once 'app/Main.php'; // always needed
Main::getHelper("Property/Property")->test();
app/Main.php
This file contains the final class "Main" which has the static method getHelper
if (!defined('DS')) define('DS', DIRECTORY_SEPARATOR);
if (!defined('PS')) define('PS', PATH_SEPARATOR);
if (!defined('BP')) define('BP', dirname(dirname(__FILE__)));
/**
* Set include path
*/
Main::register('original_include_path', get_include_path());
$paths = array();
$paths[] = Main::CORE_PATH;
$paths[] = Main::LOCAL_PATH;
$paths[] = BP . DS . 'lib';
$paths[] = BP . DS . 'inc';
$appPath = implode(PS, $paths);
set_include_path($appPath . PS . Main::registry('original_include_path'));
final class Main
{
const CORE_PATH = BP . DS . 'app' . DS . 'code' . DS . 'core';
const LOCAL_PATH = BP . DS . 'app' . DS . 'code' . DS . 'local';
/**
* Registry collection
*
* #var array
*/
static private $_registry = array();
public static function getDbConnection()
{
return self::registry("db_connection");
}
/**
* Register a new variable
*
* #param string $key
* #param mixed $value
* #param bool $graceful
*/
public static function register($key, $value, $graceful = false)
{
if (isset(self::$_registry[$key])) {
if ($graceful) {
return;
}
self::throwException('Main registry key "'.$key.'" already exists');
}
self::$_registry[$key] = $value;
}
/**
* Unregister a variable from register by key
*
* #param string $key
*/
public static function unregister($key)
{
if (isset(self::$_registry[$key])) {
if (is_object(self::$_registry[$key]) && (method_exists(self::$_registry[$key], '__destruct'))) {
self::$_registry[$key]->__destruct();
}
unset(self::$_registry[$key]);
}
}
/**
* Retrieve a value from registry by a key
*
* #param string $key
* #return mixed
*/
public static function registry($key)
{
if (isset(self::$_registry[$key])) {
return self::$_registry[$key];
}
return null;
}
public static function getHelper($name)
{
$classPath = self::getClassPath($name, "Helper");
if (!$classPath) { return false; }
$fullClassPath = self::getFullClassPath($classPath);
if (!$fullClassPath) { return false; }
$obj = self::getClassInstance($fullClassPath, $classPath);
if (!$obj) { return false; }
return $obj;
}
public static function getModel($name)
{
$classPath = self::getClassPath($name, "Model");
if (!$classPath) { return false; }
$fullClassPath = self::getFullClassPath($classPath);
if (!$fullClassPath) { return false; }
$obj = self::getClassInstance($fullClassPath, $classPath);
if (!$obj) { return false; }
return $obj;
}
private function getClassInstance($fullClassPath, $classPath)
{
if (!$classPath) { return false; }
require_once($fullClassPath);
$className = str_replace("/", "_", $classPath);
if (class_exists($className)) {
return new $className(self::getDbConnection());
} else {
return false;
}
}
private function getFullClassPath($classPath)
{
$modulPaths = [self::CORE_PATH, self::LOCAL_PATH];
return self::checkIfFileExistInModule($modulPaths, $classPath);
}
private function getClassPath($modelName, $identifier="Model")
{
if (strpos($modelName, '/') === false) { return false; }
if (substr_count($modelName, "/") == 1) {
$exp = explode("/", $modelName);
return $exp[0] . "/$identifier/" . $exp[1];
} else {
return false;
}
}
private function checkIfFileExistInModule($modulPaths, $modelname)
{
foreach($modulPaths as $path) {
$path = $path . DS . $modelname . ".php";
if (file_exists($path)) {
return $path;
}
}
return "0";
}
}
This works just fine... now the actual question.
If I am writing...
$obj = Main::getHelper("Property/Property");
$obj->
...then my IDE (NetBeans) does not auto suggest the public methods/properties which I can use.
Is there a way to "teach" my logic to add auto suggestion / auto completion so that it automatically shows all public methods/properties available in the object?

You need to use phpdoc blocks. Pretty sure they are supported by NetBeans:
/** #var Property_Helper_Property $obj */
$obj = Main::getHelper("Property/Property");
From that point forward auto-completion and static analysis will work, since it will be understood that $obj will be an instance of Property_Helper_Property.

Related

I am having an issue with the twig template system

I have opencart 3 installed on my dev box and have suddenly started getting the following error:
Fatal error: Class Twig_Loader_Filesystem contains 2 abstract methods
and must therefore be declared abstract or implement the remaining
methods (Twig_LoaderInterface::isFresh,
Twig_ExistsLoaderInterface::exists) in
/mnt/c/wsl/server/opencart/system/library/template/Twig/Loader/Filesystem.php
on line 17
I have been working on a custom template and all was going fine until I changed something in the controller of the footer. Changing it back did not resolve the issue. I have also manually cleared the cache in the OC folder and the twig folder. I also did not have the cache setting set to off so I manually made this change in the db as I get the same error trying to get into the admin.
I am at a loss. I would love any help I could get.
Call Stack
{main}( )
start( )
require_once( '/mnt/c/wsl/server/opencart/system/framework.php' )
Router->dispatch( )
Router->execute( )
Action->execute( )
ControllerStartupRouter->index( )
Action->execute( )
ControllerCommonHome->index( )
Loader->controller( )
Action->execute( )
ControllerCommonColumnLeft->index( )
Loader->view( )
Template->render( )
Template\Twig->render( )
spl_autoload_call ( )
Twig_Autoloader::autoload( )
require( '/mnt/c/wsl/server/opencart/system/library/template/Twig/Loader/Filesystem.php'
)
Location
.../index.php:0
.../index.php:19
.../startup.php:104
.../framework.php:165
.../router.php:56
.../router.php:67
.../action.php:79
.../router.php:25
.../action.php:79
.../home.php:12
.../loader.php:48
.../action.php:79
.../column_left.php:72
.../loader.php:125
.../template.php:51
.../twig.php:20
.../twig.php:20
.../Autoloader.php:51
class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
{
/** Identifier of the main namespace. */
const MAIN_NAMESPACE = '__main__';
protected $paths = array();
protected $cache = array();
protected $errorCache = array();
/**
* Constructor.
*
* #param string|array $paths A path or an array of paths where to look for templates
*/
public function __construct($paths = array())
{
if ($paths) {
$this->setPaths($paths);
}
}
/**
* Returns the paths to the templates.
*
* #param string $namespace A path namespace
*
* #return array The array of paths where to look for templates
*/
public function getPaths($namespace = self::MAIN_NAMESPACE)
{
return isset($this->paths[$namespace]) ? $this->paths[$namespace] : array();
}
/**
* Returns the path namespaces.
*
* The main namespace is always defined.
*
* #return array The array of defined namespaces
*/
public function getNamespaces()
{
return array_keys($this->paths);
}
/**
* Sets the paths where templates are stored.
*
* #param string|array $paths A path or an array of paths where to look for templates
* #param string $namespace A path namespace
*/
public function setPaths($paths, $namespace = self::MAIN_NAMESPACE)
{
if (!is_array($paths)) {
$paths = array($paths);
}
$this->paths[$namespace] = array();
foreach ($paths as $path) {
$this->addPath($path, $namespace);
}
}
/**
* Adds a path where templates are stored.
*
* #param string $path A path where to look for templates
* #param string $namespace A path name
*
* #throws Twig_Error_Loader
*/
public function addPath($path, $namespace = self::MAIN_NAMESPACE)
{
// invalidate the cache
$this->cache = $this->errorCache = array();
if (!is_dir($path)) {
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
}
$this->paths[$namespace][] = rtrim($path, '/\\');
}
/**
* Prepends a path where templates are stored.
*
* #param string $path A path where to look for templates
* #param string $namespace A path name
*
* #throws Twig_Error_Loader
*/
public function prependPath($path, $namespace = self::MAIN_NAMESPACE)
{
// invalidate the cache
$this->cache = $this->errorCache = array();
if (!is_dir($path)) {
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
}
$path = rtrim($path, '/\\');
if (!isset($this->paths[$namespace])) {
$this->paths[$namespace][] = $path;
} else {
array_unshift($this->paths[$namespace], $path);
}
}
/**
* {#inheritdoc}
*/
public function getSource($name)
{
return file_get_contents($this->findTemplate($name));
}
/**
* {#inheritdoc}
*/
public function getCacheKey($name)
{
return $this->findTemplate($name);
}
/**
* {#inheritdoc}
*/
public function exists($name)
{
$name = $this->normalizeName($name);
if (isset($this->cache[$name])) {
return true;
}
try {
return false !== $this->findTemplate($name, false);
} catch (Twig_Error_Loader $exception) {
return false;
}
}
/**
* {#inheritdoc}
*/
public function isFresh($name, $time)
{
return filemtime($this->findTemplate($name)) <= $time;
}
protected function findTemplate($name)
{
$throw = func_num_args() > 1 ? func_get_arg(1) : true;
$name = $this->normalizeName($name);
if (isset($this->cache[$name])) {
return $this->cache[$name];
}
if (isset($this->errorCache[$name])) {
if (!$throw) {
return false;
}
throw new Twig_Error_Loader($this->errorCache[$name]);
}
$this->validateName($name);
list($namespace, $shortname) = $this->parseName($name);
if (!isset($this->paths[$namespace])) {
$this->errorCache[$name] = sprintf('There are no registered paths for namespace "%s".', $namespace);
if (!$throw) {
return false;
}
throw new Twig_Error_Loader($this->errorCache[$name]);
}
foreach ($this->paths[$namespace] as $path) {
if (is_file($path.'/'.$shortname)) {
if (false !== $realpath = realpath($path.'/'.$shortname)) {
return $this->cache[$name] = $realpath;
}
return $this->cache[$name] = $path.'/'.$shortname;
}
}
$this->errorCache[$name] = sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]));
if (!$throw) {
return false;
}
throw new Twig_Error_Loader($this->errorCache[$name]);
}
protected function parseName($name, $default = self::MAIN_NAMESPACE)
{
if (isset($name[0]) && '#' == $name[0]) {
if (false === $pos = strpos($name, '/')) {
throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "#namespace/template_name").', $name));
}
$namespace = substr($name, 1, $pos - 1);
$shortname = substr($name, $pos + 1);
return array($namespace, $shortname);
}
return array($default, $name);
}
protected function normalizeName($name)
{
return preg_replace('#/{2,}#', '/', str_replace('\\', '/', (string) $name));
}
protected function validateName($name)
{
if (false !== strpos($name, "\0")) {
throw new Twig_Error_Loader('A template name cannot contain NUL bytes.');
}
$name = ltrim($name, '/');
$parts = explode('/', $name);
$level = 0;
foreach ($parts as $part) {
if ('..' === $part) {
--$level;
} elseif ('.' !== $part) {
++$level;
}
if ($level < 0) {
throw new Twig_Error_Loader(sprintf('Looks like you try to load a template outside configured directories (%s).', $name));
}
}
}
}

Fatal error: Call to a member function execute() on null in ..../abstractmodel.php 98 [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I try to learn how to make MVC model, but i have the following errors:
Notice: Sorry no method prepare has been found in ......./pdodatabasehandler.php 27
Fatal error: Call to a member function execute() on null in ..../abstractmodel.php 98
databasehandler.php
<?php
namespace BATRAHOSTMVC\Lib\Database;
/**
* Description of DatabaseHandler
*
* #author Mohamed Hassan Elmetwaly
* 25-03-2017
* mhe.developer#gmail.com
*/
abstract class DatabaseHandler {
const DATABASE_DRIVER_POD = 1;
const DATABASE_DRIVER_MYSQLI = 2;
private function __construct() {
}
abstract protected static function init();
abstract protected static function getInstance();
public static function factory()
{
// $driver = DATABASE_CONN_DRIVER;
// if($driver == self::DATABASE_DRIVER_POD)
// {
return PDODatabaseHandler::getInstance();
// } else if ($driver == self::DATABASE_DRIVER_MYSQLI)
// {
// return MySQLiDatabaseHandler::getInstance();
// }
}
}
pdodatabasehandler.php
<?php
namespace BATRAHOSTMVC\Lib\Database;
/**
* Description of pdodatabasehandler
* #author Mohamed Hassan Elmetwaly
* 25-03-2017
* mhe.developer#gmail.com
*/
class PDODatabaseHandler extends DatabaseHandler
{
private static $_instance;
private static $_handler;
private function __construct() {
self::init();
}
//public function __call($name, $arguments) {}
public function __call($name, $arguments) {
if(method_exists($this, $name))
{
$this->$name($arguments);
} else {
trigger_error('Sorry no method '. $name. ' has been found');
}
}
protected static function init(){
try{
self::$_handler = new \PDO(
'mysql:host='.DATABASE_HOST_NAME.';dbname='.DATABASE_DB_NAME,DATABASE_USER_NAME,
DATABASE_PASSW0RD);
//var_dump(self::$_handler);
//self::$_handler = new pdo("mysql:host=localhost; dbname=test", 'root', 'rootbootroot');
//return 'Connected';
} catch (\PDOException $e)
{
echo $e->getMessage( ) ." | ". $e->getCode( ) ;
}
}
public static function getInstance() {
if(self::$_instance === null){
self::$_instance = new self();
}
return self::$_instance;
}
}
abstractmodel.php
<?php
namespace BATRAHOSTMVC\Models;
use BATRAHOSTMVC\Lib\Database\DatabaseHandler;
//echo DATABASE_DB_NAME;
/**
* Description of abstractmodel
* #author Mohamed Hassn Elmetwaly (25-03-2017)
* mhe.developer#gmail.com
*/
class AbstractModel
{
const DATA_TYPE_BOOL = \PDO::PARAM_BOOL;
const DATA_TYPE_STR = \PDO::PARAM_STR;
const DATA_TYPE_INT = \PDO::PARAM_INT;
const DATA_TYPE_DECIMAL = 4;
const DATA_TYPE_DATE = 5;
/*
public static function viewTableSchema()
{
return static::$tableSchema;
}
*
*/
// we make path by reference
private function prepareValues(\PDOStatement &$stmt)
{
foreach (static::$tableSchema as $columnName => $type)
{
if($type == 4)
{
$sanitizedValue = filter_var($this->$columnName, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
$stmt->bindValue(":{$columnName}", $sanitizedValue);
}
else
{
$stmt->bindValue(":{$columnName}", $this->$columnName, $type);
}
}
}
private static function buildNameParametersSQL()
{
$nameParams = '';
//$columnName (Column Name) => $type (Column datatype)
foreach (static::$tableSchema as $columnName => $type)
{
$nameParams .= $columnName. ' = :'.$columnName. ', ';
}
return trim($nameParams, ', ');
}
private static function create()
{
//global $connection;
$sql = 'INSERT INTO '. static::$tableName . ' SET '. self::buildNameParametersSQL();
$stmt = DatabaseHandler::factory()->prepare($sql);
$this->prepareValues($stmt);
return $stmt->execute(); // true of false
}
private static function update()
{
// global $connection;
$sql = 'UPDATE '. static::$tableName . ' SET '. self::buildNameParametersSQL(). ' WHERE '. static::$primaryKey .' = '.$this->{static::$primaryKey};
// $stmt = $connection->prepare($sql);
//$stmt = DatabaseHandler::factory()->prepare($sql);
$stmt = DatabaseHandler::factory()->prepare($sql);
$this->prepareValues($stmt);
return $stmt->execute(); // true of false
}
public function save()
{
return $this->{static::$primaryKey} === null ? $this->create() : $this->update();
}
public static function delete()
{
// global $connection;
$sql = 'DELETE FROM '. static::$tableName . ' WHERE '. static::$primaryKey .' = '.$this->{static::$primaryKey};
// $stmt = $connection->prepare($sql);
$stmt = DatabaseHandler::factory()->prepare($sql);
return $stmt->execute(); // true of false
}
public static function getAll()
{
// global $connection;
$sql = 'SELECT * FROM '. static::$tableName;
//$stmt = $connection->prepare($sql);
$stmt = DatabaseHandler::factory()->prepare($sql);
//return $connection->execute() === true ? $stmt->fetchAll(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, 'Employee', array('name', 'age', 'address', 'tax', 'salary')) : false;
//using fetchAll with this paramaters return values as OBJECT Of class which returned by get_called_calss() which called this method
$stmt->execute();
$result = $stmt->fetchAll(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, get_called_class(), array_keys(static::$tableSchema));
return is_array($result) && !empty($result) === true ? $result : false;
}
public static function getByPk($pk)
{
//global $connection;
$sql = 'SELECT * FROM '. static::$tableName. ' WHERE '. static::$primaryKey .' = '.$pk;
//$stmt = $connection->prepare($sql);
//$stmt = DatabaseHandler::factory()->prepare($sql);
$stmt = DatabaseHandler::factory()->prepare($sql);
//return $connection->execute() === true ? $stmt->fetchAll(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, 'Employee', array('name', 'age', 'address', 'tax', 'salary')) : false;
//using fetchAll with this paramaters return values as OBJECT Of class which returned by get_called_calss() which called this method
if($connection->execute() === true)
{
$obj = $stmt->fetchAll(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, get_called_class(), array_keys(static::$tableSchema));
return array_shift($obj);
}
return false;
}
public static function get($sql, $options = array())
{
/*
* example:
* $emps = Employee::get(
* 'SELECT name, age FROM employees WHERE age = :age',
* array(
* 'age' => array(Employee::DATA_TYPE_INT, 34)
* )
* )
* var_dump($emps)
*/
//global $connection;
//$stmt = $connection->prepare($sql);
$stmt = DatabaseHandler::factory()->prepare($sql);
if(!empty($options))
{
foreach ($options as $columnName => $type)
{
//$type[0] = datatype, $type[1] = columname
if($type[0] == 4)
{
$sanitizedValue = filter_var($type[1], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
$stmt->bindValue(":{$columnName}", $sanitizedValue);
}
else
{
$stmt->bindValue(":{$columnName}", $type[1], $type[0]);
}
}
}
$stmt->execute();
$result = $stmt->fetchAll(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, get_called_class(), array_keys(static::$tableSchema));
return is_array($result) && !empty($result) === true ? $result : false;
/*
if(method_exists(get_called_class(), '__construct')){
$result = $stmt->fetchAll(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, get_called_class(), array_keys(static::$tableSchema));
//return is_array($result) && !empty($result) === true ? $result : false;
} else {
$result =$stmt->fetchAll(\PDO::FETCH_CLASS, get_called_class());
}
if((is_array($result) && !empty($result))){
$generator = function() use ($result){};
return $generator;
}
return false;
*/
}
}
employeecontroller.php
<?php
/**
* Description of abstractcontroller
*
* #author Mohamed Hassn Elmetwaly (25-03-2017)
* mhe.developer#gmail.com
*/
namespace BATRAHOSTMVC\Controllers;
use BATRAHOSTMVC\Models\EmployeeModel;
class EmployeeController extends AbstractController
{
public function defaultAction()
{
//EmployeeModel::getAll();
var_dump(EmployeeModel::getAll());
$this->_view();
}
}
employeemodel.php
<?php
namespace BATRAHOSTMVC\Models;
//use BATRAHOSTMVC\Models\AbstractModel;
//use BATRAHOSTMVC\Models\AbstractModel;
/**
* Description of employee
* #author Mohamed Hassn Elmetwaly (25-03-2017)
* mhe.developer#gmail.com
*/
class EmployeeModel extends AbstractModel
{
public $id;
public $name;
public $age;
public $address;
public $tax;
public $salary;
public static $db;
protected static $tableName = 'employees';
protected static $tableSchema = array(
'name' => self::DATA_TYPE_STR,
'age' => self::DATA_TYPE_INT,
'address' => self::DATA_TYPE_STR,
'tax' => self::DATA_TYPE_DECIMAL,
'salary' => self::DATA_TYPE_DECIMAL
);
protected static $primaryKey = 'id';
public function __construct($name, $age, $address, $tax, $salary) {
$this->name = $name;
$this->age = $age;
$this->address = $address;
$this->tax = $tax;
$this->salary = $salary;
}
public function __get($prop){
$this->$prop;
}
public function getTableName(){
return self::$tableName;
}
}
autoload.php
<?php
namespace BATRAHOSTMVC\LIB;
/*
* Applcation Constants
*/
/*
define('DS', DIRECTORY_SEPARATOR);
define('APP_PATH', dirname(realpath(__FILE__)).DS.'..');
define('PS', PATH_SEPARATOR);
define('CONTROLLER_PATH', APP_PATH.DS.'controllers');
define('MODEL_PATH', APP_PATH.DS.'models');
//echo CONTROLLER_PATH;
$path = get_include_path().PS.CONTROLLER_PATH.PS.MODEL_PATH;
set_include_path($path);
*/
class Autoload
{
public static function autoload($classname)
{
/* in Explanation */
$classname = str_replace('BATRAHOSTMVC', '',$classname);
$classname = str_replace('\\', '/', $classname);
$classname = $classname.'.php';
$classname = strtolower($classname);
if(file_exists(APP_PATH.$classname))
{
require_once APP_PATH.$classname;
}
/*
$class = str_replace('\\', '/', $classname);
$classFile = APP_PATH.DIRECTORY_SEPARATOR.strtolower($class).'.php';
if(file_exists($classFile))
{
require $classFile;
}
else
{
return;
}
*/
}
}
spl_autoload_register(__NAMESPACE__.'\Autoload::autoload');
frontcontroller.php
<?php
namespace BATRAHOSTMVC\LIB;
class FrontController
{
const NOT_FOUND_ACTION = 'notFoundAction';
const NOT_FOUND_CONTROLLER = 'BATRAHOSTMVC\Controllers\NotFoundController';
private $_controller = 'index';
private $_action = 'default';
private $_params = array();
public function __construct() {
$this->_parseUrl();
}
private function _parseUrl()
{
$url = explode('/', trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH),'/'), 3);
var_dump($url);
if(isset($url[0]) && $url[0] !='')
{
$this->_controller = $url[0];
}
if(isset($url[1]) && $url[1] !='')
{
$this->_action = $url[1];
}
if(isset($url[2]) && $url[2] !='')
{
$this->_params = explode('/', $url[2]);
}
// #list($this->_controller, $this->_action, $this->_params) = explode('/', trim($url, '/'),3);
// $this->_params = explode('/', $this->_params);
var_dump($this);
}
public function dispatch()
{
$controllerClassName = 'BATRAHOSTMVC\Controllers\\'.ucfirst($this->_controller).'Controller';
$actionName = $this->_action.'Action';
if(!class_exists($controllerClassName))
{
$controllerClassName = self::NOT_FOUND_CONTROLLER;
}
$controller = new $controllerClassName();
if(!method_exists($controller, $actionName))
{
$this->_action = $actionName = self::NOT_FOUND_ACTION;
}
$controller->setController($this->_controller);
$controller->setAction($this->_action);
$controller->setParams($this->_params);
$controller->$actionName();
}
}
I attached my files in the following link
http://www.mediafire.com/file/mdbxj5o3f6hd3gz/mvcyahia%285-4-2017%29.rar
Thanks in advance
public static function getInstance() {
if(self::$_instance === null){
self::$_instance = new self();
}
// here was the confusing the old value was return self::$_instance
return self::$_handler;
}
Your database / query object is null. So find how you call the database object so you can call its method.
Your code shows no prepare() method defined for your db class.
You are setting your PDODatabaseHandler::_handler property to the PDO, but when you are returning self(). Get it?

How do you use namespacing with php packages and phpunit?

EDITED to add code for MainClass as requested in comments.
I'm trying to learn how to make php packages and how to use phpunit at the same time, I may be using all the wrong terminology here and doing everything wrong..
Everything works as expected when I import the package with composer. I decided to add some unit tests as I finally started to see how they could be useful to me however I am having trouble and I suspect it has something to do with namespaces but I'm not sure.
I have put the tests in their own directory and used use statements at the top of the test classes for importing the main src classes. So, for example, in a test class I have the following:
use myname\Package\MainClass;
use myname\Package\Resources\Resource;
use myname\Package\Resources\ExtendedResource;
class ResourceTest extends PHPUnit_Framework_TestCase {
public function testArtistIsResource() {
$resource = '\\myname\\Package\\Resources\\Resource';
$main = new MainClass('Artist');
$artist = $main->find(1383508);
$this->assertTrue($artist instanceof $resource);
}
}
This test passes. I am running the same code outside of the test directory and displaying values in the browser to see what happens. I am running the package in laravel and just running the comparison code on the homepage. For example the output of the following code is printed directly in the browser
$main = new MainClass('Artist');
$artist = $main->find(1383508);
echo get_class($main);
echo get_class($artist);
This shows that $main is a myname\Package\MainClass and $artist is a myname\Package\Resources\ExtendedResource. If I change the second echo statement above to this:
echo get_class($artist->get());
Then the result is that stdClass is echoed to the screen, which is correct. However in the test class $artist->get() returns an instance of ResourceTest and I don't understand why it is not another stdClass.
What am I missing?
My directory structure is as follows:
myname
|- Package
|- composer.json
|- src
|- MainClass.php
|- Resources
|- Resource.php
|- ExtendsResource.php
|- tests
|- Resources
|- ResourceTest.php
Below is the content of the autoload part of composer.json
"autoload": {
"psr-4": {
"myname\\Package\\": "src/"
}
}
I tried adding another namespace in there - "myname\Package\tests\": "tests/" - but that didn't seem to help.
The namespace for MainClass.php is myname\Package.
The namespace for Resources.php and ExtendsResources.php is myname\Package\Resources.
Here is the code for MainClass.php
<?php
namespace myname\Package;
class MainClass {
private $resource;
public function __construct($resource = null) {
Container::setup();
if ($resource) {
$this->resource = Container::get($resource);
}
return $this->resource;
}
public function find($id) {
if (isset ($this->resource)) {
$this->resource->find($id);
return $this->resource;
}
else { throw new \Exception('Resource is not set'); }
}
public function setResource($resource) {
$this->resource = Container::get($resource);
return $this->resource;
}
}
Below is the code for myname\Package\Resources\Reource
<?php
namespace myname\Package\Resources;
use myname\Package\Contracts\ConfigInterface;
use myname\Package\Contracts\GrabberInterface;
use myname\Package\Contracts\ResourceInterface;
use myname\Package\Http\Grabber;
use myname\Package\Http\Poster;
abstract class Resource {
protected $config = null;
protected $url = null;
protected $resource = null;
protected $response = null;
protected $grabber = null;
protected $perPage = null;
protected $page = null;
protected $params = null;
protected $token = null;
protected $identifier = null;
protected $update = array();
protected $appendTokenTo = array(
'myname\Package\Resources\Artist',
'myname\Package\Resources\Listing',
'myname\Package\Resources\Release',
'myname\Package\Resources\Search'
);
public function __construct($config, $grabber) {
if ($config instanceof ConfigInterface) {
$this->config = $config;
} else { throw new \Exception('The supplied $config is not an instance of ConfigInterface'); }
if ($grabber instanceof GrabberInterface) {
$this->grabber = $grabber;
} else { throw new \Exception('The supplied $grabber is not an instance of GrabberInterface'); }
$this->url .= $this->config->getApiUrl() . $this->resource;
$this->token = $this->config->getApiToken();
return $this;
}
public function addParam($param, $value) {
$value= $this->formatParamValue($value);
$this->params .= "&". "$param=$value";
return $this;
}
protected function addToken(){
$this->addParam('token', $this->token);
//$this->params .= "&". "token=$this->token";
return $this;
}
public function addUpdate($update, $value) {
$this->update[$update] = $value;
return $this;
}
protected function checkIfTokenIsRequired() {
if (in_array(get_class($this), $this->appendTokenTo)) {
$this->addToken();
}
}
public function find($identifier) {
if (empty ($this->identifier)) {
$this->identifier = $identifier;
$this->url .= "/$identifier";
}
return $this;
}
protected function formatParamValue($value) {
$value = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $value);
$value = str_replace(' ', '+', $value);
return $value;
}
public function get() {
return json_decode($this->getResponse());
}
protected function getResponse() {
if (!isset($this->response)) {
$this->checkIfTokenIsRequired();
$this->_prepare();
}
return $this->response;
}
public function json() {
return $this->getResponse();
}
public function page($pageNumber) {
$this->page = $pageNumber;
return $this;
}
public function perPage($resultsPerPage) {
$this->perPage = $resultsPerPage;
return $this;
}
protected function _prepare() {
$params = 0;
if (isset($this->page) OR isset($this->perPage) OR isset($this->params)){
$this->url .= '?';
}
if (isset($this->params)) {
$this->url .= "$this->params";
$params++;
}
if (isset($this->perPage)) {
if ($params > 0) {
$this->url .= '&';
}
$this->url .= "per_page=$this->perPage";
$params++;
}
if (isset($this->page)) {
if ($params > 0) {
$this->url .= '&';
}
$this->url .= "page=$this->page";
$params++;
}
$this->grabber->setUrl($this->url);
$this->response = $this->grabber->grab();
}
public function setGrabber($grabber) {
if ($grabber instanceof GrabberInterface) {
$this->grabber = $grabber;
} else { throw new \Exception($grabber . " is not an instance of GrabberInterface"); }
}
public function setUrl($url) {
$this->url = $url;
}
public function update() {
//$this->update['token'] = $this->token;
$this->grabber->setMethod('POST');
$this->grabber->setUpdates(json_encode($this->update));
$this->_prepare();
return $this;
}
}
Below is the code for the ExtendedResource
<?php
namespace myname\Package\Resources;
class ExtendedResource extends Resource {
protected $resource = 'artists';
/**
* Returns the releases associated with an artist
*
* #return $this
*/
public function releases() {
$this->url .= '/releases';
return $this;
}
}

How to Integrate SEOStats with Codeigniter?

Hello I want to integrate the SEOStats Class with a project in codeigniter , is anyone provide me solution ?
I have tried to make the SEOstats class as a helper and load the helper in the specific controler , but a blank page is showing , I also try to include it via view but the same blank page i am seeing ,
I have included this code in my view file , the SEOstats directory also in the same views directory .
<?php
require_once 'SEOstats/bootstrap.php';
use \SEOstats\Services as SEOstats;
try {
$url = 'http://www.google.com/';
// Create a new SEOstats instance.
$seostats = new \SEOstats\SEOstats;
// Bind the URL to the current SEOstats instance.
if ($seostats->setUrl($url)) {
echo SEOstats\Alexa::getGlobalRank();
echo SEOstats\Google::getPageRank();
}
}
catch (SEOstatsException $e) {
die($e->getMessage());
}
i have also used it as library
<?php
namespace SEOstats;
use SEOstats\Common\SEOstatsException as E;
use SEOstats\Config as Config;
use SEOstats\Helper as Helper;
use SEOstats\Services as Service;
class SEOstats
{
const BUILD_NO = Config\Package::VERSION_CODE;
protected static $_url,
$_host,
$_lastHtml,
$_lastLoadedUrl
= false;
public function __construct($url = false)
{
if (false !== $url) {
self::setUrl($url);
}
}
public function Alexa()
{
return new Service\Alexa;
}
public function Google()
{
return new Service\Google;
}
public function OpenSiteExplorer()
{
return new Service\OpenSiteExplorer;
}
public function SEMRush()
{
return new Service\SemRush;
}
public function Sistrix()
{
return new Service\Sistrix;
}
public function Social()
{
return new Service\Social;
}
public static function getHost()
{
return self::$_host;
}
public static function getLastLoadedHtml()
{
return self::$_lastHtml;
}
public static function getLastLoadedUrl()
{
return self::$_lastLoadedUrl;
}
/**
* Ensure the URL is set, return default otherwise
* #return string
*/
public static function getUrl($url = false)
{
$url = false !== $url ? $url : self::$_url;
return $url;
}
public function setUrl($url)
{
if (false !== Helper\Url::isRfc($url)) {
self::$_url = $url;
self::$_host = Helper\Url::parseHost($url);
}
else {
throw new E('Invalid URL!');
exit();
}
return true;
}
/**
* #return DOMDocument
*/
protected static function _getDOMDocument($html) {
$doc = new \DOMDocument;
#$doc->loadHtml($html);
return $doc;
}
/**
* #return DOMXPath
*/
protected static function _getDOMXPath($doc) {
$xpath = new \DOMXPath($doc);
return $xpath;
}
/**
* #return HTML string
*/
protected static function _getPage($url) {
$url = self::getUrl($url);
if (self::getLastLoadedUrl() == $url) {
return self::getLastLoadedHtml();
}
$html = Helper\HttpRequest::sendRequest($url);
if ($html) {
self::$_lastLoadedUrl = $url;
self::_setHtml($html);
return $html;
}
else {
self::noDataDefaultValue();
}
}
protected static function _setHtml($str)
{
self::$_lastHtml = $str;
}
protected static function noDataDefaultValue()
{
return Config\DefaultSettings::DEFAULT_RETURN_NO_DATA;
}
}
and loaded the library as
$this->load->library('SEOstats');
I know this post is old. But I was looking for a solution as well recently and ended up writing my own and figured I would leave it here in case anyone else was looking for a solution in the future.
Place the following in a library file and autoload if you want.
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class SEOstatistics {
private $seostats;
function __construct() {
require_once( APPPATH . 'third_party/seostats/bootstrap.php' );
$this->seostats = new \SEOstats\SEOstats;
}
private function alexa() {
return new \SEOstats\Services\Alexa;
}
private function google() {
return new \SEOstats\Services\Google;
}
private function moz() {
return new \SEOstats\Services\Mozscape();
}
private function openSiteExplorer() {
return new \SEOstats\Services\OpenSiteExplorer();
}
private function semRush() {
return new \SEOstats\Services\SemRush();
}
private function sistrix() {
return new \SEOstats\Services\Sistrix();
}
private function social() {
return new \SEOstats\Services\Social();
}
public function __call($method, $url) {
if (method_exists($this, $method)) {
if ($this->seostats->setUrl($url[0])) {
return call_user_func_array(array($this, $method),array());
}
return false;
}
}
}
And then an example of using it in a controller or model is:
$google = $this->seostatistics->google($url);
$rank = $google->getPageRank();
This is how I include SEOStats on my Codeigniter website
class Cron extends Frontend_Controller
{
public function get_google_page_rank() {
require_once (APPPATH . 'libraries/SEOstats/bootstrap.php');
try {
$url = 'http://www.google.com/';
// Get the Google PageRank for the given URL.
$pagerank = \SEOstats\Services\Google::getPageRank($url);
echo "The current Google PageRank for {$url} is {$pagerank}." . PHP_EOL;
}
catch(\Exception $e) {
echo 'Caught SEOstatsException: ' . $e->getMessage();
}
}
public function get_alexa_page_rank() {
require_once (APPPATH . 'libraries/SEOstats/bootstrap.php');
//use \SEOstats\Services\Alexa as Alexa;
try {
$url = 'https://www.google.com/';
// Create a new SEOstats instance.
$seostats = new \SEOstats\SEOstats;
// Bind the URL to the current SEOstats instance.
if ($seostats->setUrl($url)) {
/**
* Print HTML code for the 'daily traffic trend'-graph.
*/
echo \SEOstats\Services\Alexa::getTrafficGraph(1);
/**
* Print HTML code for the 'daily pageviews (percent)'-graph.
*/
echo \SEOstats\Services\Alexa::getTrafficGraph(2);
/**
* Print HTML code for the 'daily pageviews per user'-graph.
*/
echo \SEOstats\Services\Alexa::getTrafficGraph(3);
/**
* Print HTML code for the 'time on site (in minutes)'-graph.
*/
echo \SEOstats\Services\Alexa::getTrafficGraph(4);
/**
* Print HTML code for the 'bounce rate (percent)'-graph.
*/
echo \SEOstats\Services\Alexa::getTrafficGraph(5);
/**
* Print HTML code for the 'search visits'-graph, using
* specific graph dimensions of 320*240 px.
*/
echo \SEOstats\Services\Alexa::getTrafficGraph(6, false, 320, 240);
}
}
catch(\Exception $e) {
echo 'Caught SEOstatsException: ' . $e->getMessage();
}
}
}
Hope this helps
PS: Copy SEOstats folder in application/libraries folder

get set properties in php

I'm from the C# environment and I'm starting to learn PHP in school.
I'm used to set my properties in C# like this.
public int ID { get; set; }
What's the equivalent to this in php?
Thanks.
There is none, although there are some proposals for implementing that in future versions.
For now you unfortunately need to declare all getters and setters by hand.
private $ID;
public function setID($ID) {
$this->ID = $ID;
}
public function getID() {
return $this->ID;
}
for some magic (PHP likes magic), you can look up __set and __get magic methods.
Example
class MyClass {
private $ID;
private function setID($ID) {
$this->ID = $ID;
}
private function getID() {
return $this->ID;
}
public function __set($name,$value) {
switch($name) { //this is kind of silly example, bt shows the idea
case 'ID':
return $this->setID($value);
}
}
public function __get($name) {
switch($name) {
case 'ID':
return $this->getID();
}
}
}
$object = new MyClass();
$object->ID = 'foo'; //setID('foo') will be called
Thanks for your answers everyone. It helped me to create something like this:
In my parent class:
public function __get($name){
if (ObjectHelper::existsMethod($this,$name)){
return $this->$name();
}
return null;
}
public function __set($name, $value){
if (ObjectHelper::existsMethod($this,$name))
$this->$name($value);
}
ObjectHelper::existsMethod is a method which just check if given protected method exists.
private $_propertyName = null;
protected function PropertyName($value = ""){
if (empty($value)) // getter
{
if ($this-> _propertyName != null)
return $this->_propertyName;
}
else // setter
{
$this-> _propertyName = $value;
}
return null;
}
So I can use something like this in any class:
$class = new Class();
$class->PropertyName = "test";
echo $class->PropertyName;
I was inspired by C# :)
What do you think about this, guys?
Here is my ObjectHelper if someone would like to use it:
namespace Helpers;
use ReflectionMethod;
class ObjectHelper {
public static function existsMethod($obj, $methodName){
$methods = self::getMethods($obj);
$neededObject = array_filter(
$methods,
function ($e) use($methodName) {
return $e->Name == $methodName;
}
);
if (is_array($neededObject))
return true;
return false;
}
public static function getMethods($obj){
$var = new \ReflectionClass($obj);
return $var->getMethods(ReflectionMethod::IS_PROTECTED);
}
}
Mchi is right, but there is another way of doing it by using single function
private $ID;
public function ID( $value = "" )
{
if( empty( $value ) )
return $this->ID;
else
$this->ID = $value;
}
But yeah this approach is pretty much inline with what you do in c#. but this is only an alternative
Or try using php's __set and __get in your class more info here
http://php.net/manual/en/language.oop5.overloading.php
Another exampled using Variable function name
class MyClass {
private $ID;
protected $ID2;
private function setID($ID) {
$this->ID = $ID;
}
private function getID() {
return $this->ID;
}
private function setID2($ID2) {
$this->ID2 = $ID2;
}
private function getID2() {
return $this->ID2;
}
public function __set($name,$value) {
$functionname='set'.$name;
return $this->$functionname($value);
}
public function __get($name) {
$functionname='get'.$name;
return $this->$functionname();
}
}
$object = new MyClass();
$object->ID = 'foo'; //setID('foo') will be called
$object->ID2 = 'bar'; //setID2('bar') will be called
private $ID;
public function getsetID($value = NULL)
{
if ($value === NULL) {
return $this->ID;
} else {
$this->ID = $value;
}
}
I know I am a bit late to the party on this question, but I had the same question/thought myself. As a C# developer who does PHP, when the job requires, I want to have a simple way to create properties just I would be able to in C#.
I whipped up a first draft this afternoon which allows you to create the backing fields and specify their accessors or have pure accessors with no backing field. I will update my answer as the code evolves and provide a link when I get it to the state where it can be imported as a composer package.
For simplicity, I created the functionality as a PHP trait so you can drop it in to any class you want instead of having to extend a base class. Eventually I hope to extend this functionality to discern between external public calls to the properties and protected/private calls.
Here is the code for the trait itself:
trait PropertyAccessorTrait
{
private static $__propertyAccessors = [];
/* #property string $__propertyPrefix */
public function __get($name)
{
$this->__populatePropertyAcessors($name);
return $this->__performGet($name);
}
public function __set($name, $value)
{
$this->__populatePropertyAcessors($name);
$this->__performSet($name, $value);
}
public function __isset($name)
{
// TODO: Implement __isset() method.
}
public function __unset($name)
{
// TODO: Implement __unset() method.
}
protected function __getBackingFieldName($name)
{
if (property_exists(self::class, '__propertyPrefix')) {
$prefix = $this->__propertyPrefix;
} else {
$prefix = '';
}
return $prefix . $name;
}
protected function __canget($name)
{
$accessors = $this->__getPropertyAccessors($name);
return $accessors !== null && isset($accessors['get']);
}
protected function __canset($name)
{
$accessors = $this->__getPropertyAccessors($name);
return $accessors !== null && isset($accessors['set']);
}
protected function __performGet($name)
{
if (!$this->__canget($name)) {
throw new \Exception('Getter not allowed for property: ' . $name);
}
$accessors = $this->__getPropertyAccessors($name)['get'];
/* #var \ReflectionMethod $method */
$method = $accessors['method'];
if (!empty($method)) {
return $method->invoke($this);
}
return $this->{$this->__getBackingFieldName($name)};
}
protected function __performSet($name, $value)
{
if (!$this->__canset($name)) {
throw new \Exception('Setter not allowed for property: ' . $name);
}
$accessors = $this->__getPropertyAccessors($name)['set'];
/* #var \ReflectionMethod $method */
$method = $accessors['method'];
if (!empty($method)) {
return $method->invoke($this, $value);
}
$this->{$this->__getBackingFieldName($name)} = $value;
}
protected function __getPropertyAccessors($name)
{
return isset(self::$__propertyAccessors[$name])
? self::$__propertyAccessors[$name]
: null
;
}
protected function __getAccessorsFromDocBlock($docblock)
{
$accessors = [];
if (!empty(trim($docblock))) {
$doclines = null;
if (!empty($docblock)) {
$doclines = explode("\n", $docblock);
}
if (!empty($doclines)) {
foreach ($doclines as $line) {
if (preg_match('/#(get|set)\\s+(public|private|protected)/', $line, $matches)) {
$accessors[$matches[1]]['visibility'] = $matches[2];
}
}
}
}
return $accessors;
}
protected function __populatePropertyAcessors($name)
{
if ($this->__getPropertyAccessors($name) !== null) return;
try {
$property = new \ReflectionProperty(self::class, $this->__getBackingFieldName($name));
} catch (\ReflectionException $ex) {
$property = null;
}
$accessors = [];
if ($property != null) {
$accessors = $this->__getAccessorsFromDocBlock($property->getDocComment());
}
try {
$methodName = 'get' . ucfirst($name);
$method = new \ReflectionMethod(self::class, $methodName);
$method->setAccessible(true);
$accessors = array_merge($accessors, $this->__getAccessorsFromDocBlock($method->getDocComment()));
} catch (\ReflectionException $ex) {
$method = null;
}
if ($method !== null || isset($accessors['get'])) {
$accessors['get']['method'] = $method;
}
try {
$methodName = 'set' . ucfirst($name);
$method = new \ReflectionMethod(self::class, $methodName);
$method->setAccessible(true);
$accessors = array_merge($accessors, $this->__getAccessorsFromDocBlock($method->getDocComment()));
} catch (\ReflectionException $ex) {
$method = null;
}
if ($method !== null || isset($accessors['set'])) {
$accessors['set']['method'] = $method;
}
self::$__propertyAccessors[$name] = $accessors;
}
}
Here is a quick unit test I created using the Codeception format:
<?php
class PropertyAssesorTraitTestClass
{
use PropertyAccessorTrait;
private $__propertyPrefix = '_';
/**
* #get public
* #set public
*/
private $_integer = 1;
/**
* #get public
*/
private $_getonly = 100;
/**
* #set public
*/
private $_setonly;
private $_customDoubler;
private function getCustomDoubler()
{
return $this->_customDoubler * 2;
}
private function setCustomDoubler($value)
{
$this->_customDoubler = $value * 2;
}
public $publicField = 1234;
/**
* #return int
* #get public
*/
private function getPureAccessor()
{
return $this->publicField;
}
/**
* #param $value
* #set public
*/
private function setPureAccessor($value)
{
$this->publicField = $value;
}
private $_purePrivate = 256;
}
$I = new UnitTester($scenario);
$I->wantTo('Ensure properties are accessed correctly');
$instance = new PropertyAssesorTraitTestClass();
$I->assertSame(1, $instance->integer);
$instance->integer = 2;
$I->assertSame(2, $instance->integer);
$instance->integer = $instance->integer + 1;
$I->assertSame(3, $instance->integer);
$instance->integer++;
$I->assertSame(4, $instance->integer);
$I->assertSame(100, $instance->getonly);
$I->expectException('Exception', function () use ($instance) { $instance->getonly = 50; });
$instance->setonly = 50;
$I->expectException('Exception', function () use ($instance) { $a = $instance->setonly; });
$instance->customDoubler = 100;
$I->assertSame(400, $instance->customDoubler);
$I->assertSame(1234, $instance->publicField);
$instance->pureAccessor = 1000;
$I->assertSame(1000, $instance->publicField);
$instance->publicField = 1234;
$I->assertSame(1234, $instance->publicField);
$I->assertSame(1234, $instance->pureAccessor);
$I->expectException('Exception', function () use ($instance) { return $instance->purePrivate; });
I like to use this pattern:
class foo
{
//just add p as prefix to be different than method name.
protected $pData;
public funtion __construct() {}
public funtion __destruct() {}
public funtion __clone() {}
public function Data($value == "")
{
if ($value != "") {
$this->pData = $value;
}
return $this->pData;
}
}
$myVar = new foo();
//for SET
$myVar->Data("A Value");
//for GET
$item = $myVar->Data();
class MyClass
{
private $name = null;
public function __construct($name = null)
{
$this->name = $name;
}
public function __set($name, $value)
{
if (property_exists($this, $name)) {
$this->name = $value;
}
return $this;
}
public function __get($name)
{
if (property_exists($this, $name)) {
return $this->$name;
}
return null;
}
}
this is PHP ; you don't need get set
class MyClass {
public $ID;
}
$object = new MyClass();
$object->ID = 'foo';
echo $object->ID;
will work

Categories