php function undefined when it is defined - php

I am having some problem with scope i assume, but i cannot for the life of me figure out what that problem is...
I keep getting a function undefined error for the following three functions whenever they are called; addUser, removeUser, updatePlayer. Anyone have any idea what's wrong? full code below (it is a pocketmine plugin):
<?php
/*
__PocketMine Plugin__
name=X
description=X
version=0.0.1
author=X
class=X
apiversion=10
*/
class X implements Plugin {
private $api;
public $continents = array();
public $allContinents = array("NA" => 0, "SA" => 0, "AF" => 0, "AS" => 0, "OC" => 0, "EU" => 0);
public function __construct(ServerAPI $api, $server = false){
$this->api = $api;
}
public function init(){
//Initialize the on player join event handler
$this->api->addHandler("player.spawn", array($this, "onPlayerJoin"));
$this->api->addHandler("player.quit", array($this, "onPlayerQuit"));
//Setup Config
$this->path = $this->api->plugin->configPath($this);
$this->msgs = new Config($this->path . "config.yml", CONFIG_YAML, array("AuthToken" => "", "Delay" => "5"));
$this->msgs = $this->api->plugin->readYAML($this->path . "config.yml");
}
// <--- updatePlayer --->
public function updatePlayer($user) {
}
// <--- Country Handler --->
public function addUser($user, $continents, $allContinents) {
$ip = $user->ip;
$username = $user->username;
$gi = geoip_open($this->path ."GeoIP.dat",GEOIP_STANDARD);
$continent = geoip_continent_code_by_name($gi, $ip);
array_push($continents, $username);
$continents[$username] = $continent;
$allContinents[$continent] += 1;
return $continents;
return $allContinents;
}
public function removeUser($user, $continents, $allContinents) {
$username = $user->username;
$continent = $continents[$username];
unset($continents[$username]);
$allContinents[$continent] -= 1;
return $continents;
return $allContinents;
}
// <--- Rquest Ad --->
public function requestAd() {
}
/*public function send() {
while(true) {
sleep(240);
}
}
}*/
//On player join event handler
public function onPlayerJoin($user){
$username = $user->username;
addUser($user);
updatePlayer($user);
//Check if plugin is setup
if ($this->api->ban->isOp($username) && $this->msgs["AuthToken"] == "") {
$this->api->chat->sendTo(false, "Please visit X to setup X.", $username);
}
}
public function onPlayerQuit($user){
removeUser($user);
}
public function __destruct(){
}
}
?>

If you're calling them from the same class or an extended class then you need to use $this.
public function onPlayerJoin($user){
$username = $user->username;
$this->addUser($user);
$this->updatePlayer($user);
}
Unless it's a static function, then you would use self::.

You need to instantiate an instance of class X, then call the functions as members of that object. For example:
$myX = new X();
$myX->addUser();
Cheers

Related

I should get a variable declared in a class and use it into the same class but I don't receive error and it don't work

I Have this problem: I should get a variable declared in a class and use it into the same class but I don't receive error and it don't work. This is my code:
<?php
class internal {
protected $settings;
private $ctoken = '';
private $fparam = '';
private $token = '';
function __construct($ctoken, $fparam, $token){
$this->ctoken = $ctoken;
$this->fparam = $fparam;
$this->token = $token;
}
public function settings($settings = ['disable_web_page_preview' => 'false', 'parse_mode' => 'HTML', 'MySQL' => true, 'PostgreSQL' => true])
{
$this->settings = $settings;
echo 'Settings caricate!';
}
public function botAdmin($user_id = null)
{
if($user_id == NULL){
$user_id = $this->user_id;
}
if(in_array($user_id, $this->settings()['admins'])){
return true;
}else{
return false;
}
}
public function SecTest()
{
if($this->ctoken != $this->fparam or $this->token == NULL){
die("Security test: not passed, script killed.");
}else{
echo "Security test: OK. <br />";
echo json_encode($this->settings);
}
}
public function getSettings(){
return $this->settings;
}
}
I don't know what to do, I don't receive any error but if I call the method SecTest it print "null"
Before your _construct method define the variables that are specific to your class.
class internal {
private $ctoken = '';
private $fparam = '';
private $token = '';
function __construct($ctoken, $fparam, $token){
$this->ctoken = $ctoken;
$this->fparam = $fparam;
$this->token = $token;
}
Fixed, I was calling the method that echo the settings before declare the settings.

How to use SplObserver for Hook system?

I code a class for Hook system. But this is outdated. I want to use splObserver to code it.
<?php
class Event
{
private static $filters = [];
private static $actions = [];
public static function addAction($name, $callback, $priority = 10)
{
if (! isset(static::$actions[$name])) {
static::$actions[$name] = [];
}
static::$actions[$name][] = [
'priority' => (int)$priority,
'callback' => $callback,
];
}
public function doAction($name, ...$args)
{
$actions = isset(static::$actions[$name]) ? static::$actions[$name] : false;
if (! $actions) {
return;
}
// sort actions by priority
$sortArr = array_map(function ($action) {
return $action['priority'];
}, $actions);
\array_multisort($sortArr, $actions);
foreach ($actions as $action) {
\call_user_func_array($action['callback'], $args);
}
}
}
Event::addAction('action1', function(){
echo 'balabala1';
});
Event::addAction('action1', function(){
echo 'balabala2';
});
Event::doAction('action1');
Output: balabala1 balabala2
It works good.
I want to use SplObserver to re-code it and try to code but no idea.
I don't really know whether this implementation could be useful in a real life application or not but, for the sake of answering your question, here we go...
Let's imagine we have a User class that we'd like to hook with our custom functions.
First, we create a reusable trait containing the Subject logic, capable of managing "event names" to whom we can hook our actions.
trait SubjectTrait {
private $observers = [];
// this is not a real __construct() (we will call it later)
public function construct()
{
$this->observers["all"] = [];
}
private function initObserversGroup(string $name = "all")
{
if (!isset($this->observers[$name])) {
$this->observers[$name] = [];
}
}
private function getObservers(string $name = "all")
{
$this->initObserversGroup($name);
$group = $this->observers[$name];
$all = $this->observers["all"];
return array_merge($group, $all);
}
public function attach(\SplObserver $observer, string $name = "all")
{
$this->initObserversGroup($name);
$this->observers[$name][] = $observer;
}
public function detach(\SplObserver $observer, string $name = "all")
{
foreach ($this->getObservers($name) as $key => $o) {
if ($o === $observer) {
unset($this->observers[$name][$key]);
}
}
}
public function notify(string $name = "all", $data = null)
{
foreach ($this->getObservers($name) as $observer) {
$observer->update($this, $name, $data);
}
}
}
Next, we use the trait in our SplSubject User class:
class User implements \SplSubject
{
// It's necessary to alias construct() because it
// would conflict with other methods.
use SubjectTrait {
SubjectTrait::construct as protected constructSubject;
}
public function __construct()
{
$this->constructSubject();
}
public function create()
{
// User creation code...
$this->notify("User:created");
}
public function update()
{
// User update code...
$this->notify("User:updated");
}
public function delete()
{
// User deletion code...
$this->notify("User:deleted");
}
}
The last step is to implement a reusable SplObserver. This observer is able to bind himself to a Closure (anonymous function).
class MyObserver implements SplObserver
{
protected $closure;
public function __construct(Closure $closure)
{
$this->closure = $closure->bindTo($this, $this);
}
public function update(SplSubject $subject, $name = null, $data = null)
{
$closure = $this->closure;
$closure($subject, $name, $data);
}
}
Now, the test:
$user = new User;
// our custom functions (Closures)
$function1 = function(SplSubject $subject, $name, $data) {
echo $name . ": function1\n"; // we could also use $data here
};
$function2 = function(SplSubject $subject, $name, $data) {
echo $name . ": function2\n";
};
// subscribe the first function to all events
$user->attach(new MyObserver($function1), 'all');
// subscribe the second function to user creations only
$user->attach(new MyObserver($function2), 'User:created');
// run a couple of methods to see what happens
$user->create();
$user->update();
The output will be:
User:created: function2
User:created: function1
User:updated: function1
NOTE: we could use SplObjectStorage instead of an array, to store observers in the trait.

joomla component not calling any model function and controller function

I am sending a ajax request in function and calling model function but model function not calling and i also try a local controller function but not call any local function
controller
<?php
defined('_JEXEC') or die;
jimport('joomla.application.component.controller');
class IgalleryController extends JControllerLegacy
{
function __construct($config = array())
{
$config['base_path'] = JPATH_SITE.'/components/com_igallery';
parent::__construct($config);
}
function ajaxrequest()
{
//JModelLegacy::addIncludePath(JPATH_SITE . '/components/com_igallery/models', 'category');
//echo $db = JFactory::getDBO();
$model = $this->getModel('category');
$this->params = JComponentHelper::getParams('com_igallery');
$this->source = JRequest::getCmd('igsource', 'component');
//
$igid = JFactory::getApplication()->input->get('igid');
$Itemid = JFactory::getApplication()->input->get('Itemid');
$this->catid = JRequest::getInt('igid', 0);
$this->category = $model->getCategory($this->catid);
$profileId = JRequest::getInt('igpid', 0);
$profileId = $profileId == 0 ? $this->category->profile : $profileId;
$user = JFactory::getUser();
//print_r($user); die;
$this->profile = $model->getProfile($profileId);
$searchChildren = JRequest::getInt('igchild', 0);
$tags = JRequest::getVar('igtags', '');
//
$limit = JRequest::getInt('iglimit', 0);
$limit = $limit == 0 ? 1000 : $limit;
$foo = $this->foo();
print_r($foo);
$this->photoList = $model->getCategoryImagesList($this->profile, $this->catid, $tags, $searchChildren, $limit);
//
print_r($this->photoList);
}
function $this->foo()
{
return true;
}
...
in above code also print $foo variable but not get true or 1 value;
You must override function getModel() in your controller
parent model has construct:
public function getModel($name = '', $prefix = '', $config = array('ignore_request' => true))
You lacked $prefix and you also add include path of the model file if necessary
Regarding issue return value true of false, you must echo 1 for true of 0 for false and stop the process by die function. The return method will show so much html of joomla page.
function $this->foo()
{
echo 1;
die;
}

Call function inside class with $this

User::updatemain($set, $where);
This gives Fatal error: Using $this when not in object context
My user class extends from Dbase class and here is user class function:
public static function activate($set, $where) {
return $this->updatemain($set, $where);
here is dbase class (some part of):
private function query($sql = null, $params = null) {
if (!empty($sql)) {
$this->_last_statement = $sql;
if ($this->_db_object == null) {
$this->connect();
}
try {
$statement = $this->_db_object->prepare($sql, $this->_driver_options);
$params = Helper::makeArray($params);
$x = 1;
if (count($params)) {
foreach ($params as $param) {
$statement->bindValue($x, $param);
$x++;
}
}
if (!$statement->execute() || $statement->errorCode() != '0000') {
$error = $statement->errorInfo();
throw new PDOException("Database error {$error[0]} : {$error[2]}, driver error code is {$error[1]}");
exit;
}
//echo $sql;
return $statement;
} catch (PDOException $e) {
echo $this->formatException($e);
exit;
}
}
}
public function updatemain($set, $where) {
return $this->query($sql, $params);
}
this is part of Dbase class
You are calling static method so there is no $this in that context.
If you want to call other static method from given class then use self::method() but if you want to call non-static method you've got problem. First you have to create new object.
When you use static methods, you can't use $this inside
public static function activate($set, $where) {
return self::updatemain($set, $where);
}
Or you have to use singelton design
EDIT
Best solution - rewrite your class to one point access to DB object. And create Model classes to DB access. See my example code below:
core AppCore
<?php
class AppCore
{
public static $config = array();
public static $ormInit = false;
public static function init($config)
{
self::$config = array_merge(self::$config, $config);
}
public static function db($table)
{
// ORM - see http://idiorm.readthedocs.org/en/latest
if (!self::$ormInit) {
ORM::configure(self::$config['db']['connection']);
ORM::configure('username', self::$config['db']['username']);
ORM::configure('password', self::$config['db']['password']);
self::$ormInit = true;
}
return ORM::for_table($table);
}
}
User model
<?php
class UserModel
{
const TABLE = 'user';
public static function findById($u_id)
{
$result = AppCore::db(self::TABLE)->where('u_id', $u_id)->find_one();
return $result ? $result->as_array() : null;
}
}
AppCore init section
AppCore::init(array(
'db' => array(
'connection' => "mysql:dbname={$db};host={$host}",
'username' => $user,
'password' => $pass
),
));
i hope it help make your code better

Zend_Log_Writer_Db - Call to undefined method Zend_Config::insert()

I am running php 5.2.12 and Zend Framework 5.0.2
In my Bootstrap.php, I initialize our database connection, and initialize our logger... placing both in the registry.
However, when I try to log info in the IndexController.php, it gives the following message:
"*Fatal error: Call to undefined method Zend_Config::insert() in /usr/local/zendsvr/share/ZendFramework/library/Zend/Log/Writer/Db.php on line 137*"
At the bottom of this post, you will find the Zend Framework's class file, db.php , and the _write function being called.
I believe the problem is that I am getting the database connection options from my application.ini... and there is no insert() function defined in my application.ini for the database. But I dont really know how to add one to the config, or how I should be doing this.
Bootstrap.php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initConfig()
{
Zend_Registry::set('config', new Zend_Config($this->getOptions()));
}
protected function _initDatabases()
{
$this->bootstrap('multidb');
$resource = $this->getPluginResource('multidb');
$databases = Zend_Registry::get('config')->resources->multidb;
foreach ($databases as $name => $adapter)
{
$db_adapter = $resource->getDb($name);
Zend_Registry::set($name, $db_adapter);
}
}
protected function _initLog()
{
$db = Zend_Registry::get('config')->resources->multidb->as400;
$columnMapping = array('ILGID' => 'id', //1 numeric
'ILGLVL' => 'priority', //2 numeric
'ILGDTE' => 'date', //yymmdd
'ILGTME' => 'time', //hhmmss
'ILGPGM' => 'program', //40 alnum
'ILGURL' => 'url', //2100
'ILGUSR' => 'user', //30
'ILGMSG' => 'message'); //1000
$writer = new Zend_Log_Writer_Db($db, 'dwhlib.intralog', $columnMapping);
$logger = new Zend_Log($writer);
$date = new Zend_Date();
date_default_timezone_set('America/Chicago');
$logger->setEventItem('id' , 1);
$logger->setEventItem('date' , $date->get('Ymd'));
$logger->setEventItem('time' , $date->get('Hms'));
$logger->setEventItem('program' , 'testProgramName'); $logger->setEventItem('url' , $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
$logger->setEventItem('user' , gethostbyaddr($_SERVER['REMOTE_ADDR']));
Zend_Registry::set('logger', $logger);
}
}
application.ini
resources.multidb.as400.adapter = "db2"
resources.multidb.as400.host = "i5"
resources.multidb.as400.username = "removedUsername"
resources.multidb.as400.password = "removedPassword"
resources.multidb.as400.dbname = "*LOCAL"
resources.multidb.as400.default = true
IndexController.php
include("/www/zendserver/htdocs/development/application/models/as400.php");
class IndexController extends Zend_Controller_Action
{
public function init()
{
Zend_Registry::get('logger')->info("this is a test message");
}
public function indexAction()
{
// action body
}
}
as400.php
Class default_Model_As400 extends Zend_Db {
public static function ExecuteSelect($sql, $mode = Zend_Db::FETCH_ASSOC, $log = false)
{
$stmt = self::getStmt($sql);
$stmt->setFetchMode($mode);
$stmt->execute();
if($log === true) {
Zend_Registry::get('logger')->info($sql);
}
$rows = $stmt->fetchAll();
return $rows;
}
private static function getStmt($sql){
$db = Zend_Registry::get('config')->resources->multidb->as400;
$abstractAdapter = new Zend_Db_Adapter_Db2($db);
return new Zend_Db_Statement_DB2($abstractAdapter, $sql);
}
public function insert($libAndFile, $arrData){
echo "this was hit!!";
}
}
db.php
class Zend_Log_Writer_Db extends Zend_Log_Writer_Abstract
{
public function __construct($db, $table, $columnMap = null)
{
$this->_db = $db;
$this->_table = $table;
$this->_columnMap = $columnMap;
}
protected function _write($event)
{
if ($this->_db === null) {
require_once 'Zend/Log/Exception.php';
throw new Zend_Log_Exception('Database adapter is null');
}
if ($this->_columnMap === null) {
$dataToInsert = $event;
} else {
$dataToInsert = array();
foreach ($this->_columnMap as $columnName => $fieldKey) {
$dataToInsert[$columnName] = $event[$fieldKey];
}
}
$this->_db->insert($this->_table, $dataToInsert);
}
}
What is happening: you are calling a method called insert() on a Zend_Config instance.
What you want: call a method insert() through a Zend_Db_Adapter.
There is something wrong in your _initLog() bootstrap method:
$db = Zend_Registry::get('config')->resources->multidb->as400;
$writer = new Zend_Log_Writer_Db($db, 'dwhlib.intralog', $columnMapping);
Zend_Log_Writer_Db expects a Zend_Db adapter as a first constructor parameter. To fix this, since you already registered your database adapter in the registry, you should do something like this :
$dbName = Zend_Registry::get('config')->resources->multidb->as400;
$db = Zend_Registry::get($dbName);
$writer = new Zend_Log_Writer_Db($db, 'dwhlib.intralog', $columnMapping);

Categories