!class_exists is not working in magento? - php

When I run test.php, why always error on !class_exists line?
This is test.php:
<?php //test.php
require_once './app/Mage.php';
Mage::app()->setCurrentStore(0);
Mage::setIsDeveloperMode(true);
require_once("test-class.php");
?>
This is test-class.php:
<?php //test-class.php
if (!class_exists("AClass")) {
class AClass {
public function AnAction() {
return 123;
}
}
}
?>

Because the Magento bootstrap app/Mage.php registers an autoloader, your call to class_exists() triggers attempts to load a class definition for this class. This behavior can be changed by passing false:
<?php //test-class.php
if (!class_exists("AClass",false)) {
class AClass {
public function AnAction() {
return 123;
}
}
}
?>
Further, the bootstrap sets up include path arguments for use by the autoloader:
$paths[] = BP . DS . 'app' . DS . 'code' . DS . 'local';
$paths[] = BP . DS . 'app' . DS . 'code' . DS . 'community';
$paths[] = BP . DS . 'app' . DS . 'code' . DS . 'core';
$paths[] = BP . DS . 'lib';
Placing your class definition in any of the above directories will allow it to be defined whenever a definition is required.

Related

Getting error using $this when not in object context to all methods in a class except __construct() method

I have two classes in separate files. The names of classes and files are: Substitute.php and Models.php. I have some properties in class Substitute.php which I can access using $this->property_name in the __construct() method without any error. However when I try to access the same property in the another method(method test() in my case(see the code below)) in the same class (i.e., class Substitute) I get the error Fatal error: Uncaught Error: Using $this when not in object context in G:\ROHAN\eTh0\VectorVolunteers\vector\backend\models\Substitute.php:22. Line 22 being echo $this->c_day; in the method sss() (I have cut some of the code in the class, adding only the which I thought to be relevant, I'll add rest of the code in case someone requires). I access methods sss() and test() from the url by autoloader method and class Router which I have included below too:
Below this line lies the code inside Substitute.php:
EDIT1: I have added another method from Substitute class where also I get the same error.
class Substitute extends Models{
public $user_id, $c_day, $c_date;
public function __construct(){
$_SESSION['username']='user2';
echo 'constructor in class Substitute ran';
$this->user_id = $this->get_user_id();
$this->c_day = $this->upcoming_class();
}
public function sss(){
echo $this->c_day;
}
public function test(){
if(isset($_POST['select_class_subs'])){
switch ($_POST['select_class_subs']) {
case 'Next Class':
$this->c_date = date('d-M-yy', strtotime(($this->c_day)));
break;
case 'Next-to-next Class':
$this->c_date = date('d-M-yy', strtotime(($this->c_day . '+1 week')));
break;
default:
echo 'Custom class selected <br>';
break;
}
if($this->c_date==date('d-M-yy')){
echo "Sorry, but you cannot post a substitute request for a class that is scheduled to happen on the same day. <br>";
}
else{
echo "Done! <br>";
}
}
}
EDIT2: The code in the file config.php which is required in the autoloader() method(See below):
if(isset($_GET['url'])){$url = explode('/', $_GET['url']);}
require_once (ROOT . DS . 'backend' . DS . 'bootstrap.php');
EDIT2: The code of file bootstrap.php which has autloader() method:
require_once 'config.php';
// Autoloader for classes
spl_autoload_register('autoloader');
function autoloader($class_Name){
if (file_exists (ROOT . DS . 'backend' . DS .'core' . DS . $class_Name . '.php')){
require_once (ROOT . DS . 'backend' . DS . 'core' . DS . $class_Name . '.php');
}
elseif (file_exists (ROOT . DS . 'backend' . DS .'models' . DS . $class_Name . '.php')){
require_once (ROOT . DS . 'backend' . DS . 'models' . DS . $class_Name . '.php');
}
elseif (file_exists(ROOT . DS . 'backend' . DS .'views' . DS . $class_Name . '.php')){
require_once (ROOT . DS . 'backend' . DS . 'views' . DS . $class_Name . '.php');
}
elseif (file_exists(ROOT . DS . 'backend' . DS .'controllers' . DS . $class_Name . '.php')){
require_once (ROOT . DS . 'backend' . DS . 'controllers' . DS . $class_Name . '.php');
}
elseif (file_exists(ROOT . DS . 'backend' . DS .'database' . DS . $class_Name . '.php')) {
require_once (ROOT . DS . 'backend' . DS .'database' . DS . $class_Name . '.php');
}
elseif (file_exists(ROOT . DS . 'backend' . DS .'reminders' . DS . $class_Name . '.php')) {
require_once (ROOT . DS . 'backend' . DS .'reminders' . DS . $class_Name . '.php');
}
else {echo 'Class does not exist or Class file not found' . '<br>';}
}
// Route the request to router.php
if (isset($_GET['url'])) {
Router::route($url);
}
EDIT2: Code in the file that contains class Router{}:
class Router{
private static $controller_name, $method_name;
public static function route($url){
if (isset($url[0]) && $url[0] != "") {
$controller = ucwords($url[0]);
self::$controller_name = $controller;
array_shift($url);
}
if (isset($url[0]) && $url[0] != "") {
$method = ucwords($url[0]);
self::$method_name = $method;
array_shift($url);
}
$params = $url;
$init = new self::$controller_name;
if (method_exists(self::$controller_name, self::$method_name)){
call_user_func_array([self::$controller_name, self::$method_name], $params);
}
else{
if(self::$method_name!=NULL){
echo 'The requested method "' . self::$method_name . '" does not exist in ' . '"' . self::$controller_name . '" controller.';
}
}
}
Below this lies the code inside Models.php (I have included it in case someone requires. But know that I have extended this class to many other classes and all of the methods in this class work fine without any errors or warning).
class Models extends Database {
private $db, $user_id, $table, $rv_id_table_name, $av_id_table_name, $class_day;
protected function get_user_id(){
if (isset($_SESSION['username'])){
$username=$_SESSION['username'];
$sql = 'SELECT * FROM volunteers where username=:username';
$params = [
'username' => $username
];
$array = $this->query($sql, $params);
$this->user_id = $array['id'];
return $this->user_id;
}
else{
echo 'You are not signed in.' . '<br>' . 'Please sign in first.';
}
}
protected function upcoming_class(){
if (isset($_SESSION['username'])) {
$id = $this->get_user_id();
$params = [
'id' => $id
];
$sql = 'SELECT class_day FROM volunteers where id=:id';
$this->class_day = $this->query($sql, $params);
return $this->class_day['class_day'];
}
}
I want to know why am I getting the above mentioned error (in Italics) and how to remove it. I asked it because I have been trying since yesterday, with no success.
How do you use that method (sss)? Are you by chance calling it statically:
Substitute::sss();
If so, that is why you are having the issue. The method is not static. It must be called like this (as one example):
$object = new Substitute();
$object->sss();
I tried converting the properties $c_day and $c_date from class Substitute{} from public to public static and instead of using $this-> to above properties I used self:: in the methods public function sss() and public function test() and to my surprise it works. No more errors.

spl_autoload_register() in different directories

I have a file that auto loads each of my classes.
This is what it contains:
spl_autoload_register(function($class){
require_once 'classes/' . $class . '.php';
});
require_once 'functions/sanitize.php';
require_once 'functions/hash.php';
But when I require_once this file from another php file that is inside my ajax folder, it will try looking for the classes, the function will look from my classes with the path: main_folder/ajax/classes instead of just main_folder/classes.
Does anyone know how to fix this?
FIX:
spl_autoload_register(function($class){
if (file_exists('classes/' . $class . '.php')) {
require_once 'classes/' . $class . '.php';
}
elseif (file_exists('../classes/' . $class . '.php')) {
require_once '../classes/' . $class . '.php';
}
elseif (file_exists('../../classes/' . $class . '.php')) {
require_once '../../classes/' . $class . '.php';
}
You should simple use this function just once - in the main file (usually index.php) and not in another files.
However if it's not possible (but I don't see any reason when could it be not possible) you can change it for example that way:
spl_autoload_register(function($class){
if (file_exists('classes/' . $class . '.php')) {
require_once 'classes/' . $class . '.php';
}
elseif (file_exists( $class . '.php')) {
require_once $class . '.php';
}
});
Here is a proper way, It should universally work.
EDIT: Make sure to specify levels on dirname in order to find the correct path.
spl_autoload_register(function ($classname) {
$file_realpath = dirname(realpath(__FILE__), levels: 1 /* Change that? */) . DIRECTORY_SEPARATOR . dirname($classname);
$classpath = sprintf('%s' . DIRECTORY_SEPARATOR . '%s.php', $file_realpath, basename($classname, '.{php,PHP}'));
if (file_exists($classpath)) {
echo "Loading <b>$classpath</b>...<br>";
require($classpath);
}
});
You need to know the absolute path to the classes directory, then just use a full qualified path to get there.
Make sure your document root is correctly configured with your http server. Furthermore this is usually solved by routing all requests to index.php and deriving the base path (document root) from there. Here is your code modified:
spl_autoload_register(function($class) {
$resolved = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . $class . '.php';
if(file_exists($resolved)) {
require_once $resolved;
} else {
// make it known to your that a class failed to load somehow
return;
}
})
Here is another implementation that I use for simple projects

is_callable loads 'pcu2phmmr6pam3' via __autoload

I've got a weird problem going on. I'm developing my website localhost on a xampp server before uploading it to my host server. I finally finished the basic components of my website, so that it could load the homepage. Everything worked as planned.
So I decided to upload it to the host server, then I set the MySQL credentials, now it should work. Ehm.. no, it didn't. Empty page.
So I put on my gloves and started digging into the code with random expressions as
echo 'test'; so I could keep track of what was going on. It seems to run just fine until is_callable() was executed.
is_callable() should run __autoload($class), so I tried var_dump($class)
It gave me this result:
string(11) "Initializer"
string(8) "Database"
string(14) "PageController"
string(14) "BaseController"
string(14) "pcu2phmmr6pam3"
string(14) "pcu2phmmr6pam3"
Now, every class listed here should be there, besides the last two. I have NO idea where that name came from, because it's not a string I've set anywhere.
The only result Google showed me for pcu2phmmr6pam3 was another website having a similar problem.
Now the really weird stuff happens, my autoload function looks like this:
function __autoload($class) {
var_dump($class);
if (file_exists(ROOT_PATH . DS . 'site' . DS . 'class' . DS . $class . '.class.php')) {
require_once(ROOT_PATH . DS . 'site' . DS . 'class' . DS . $class . '.class.php');
} else if (file_exists(ROOT_PATH . DS . 'site' . DS . 'controller' . DS . $class . '.class.php')) {
require_once(ROOT_PATH . DS . 'site' . DS . 'controller' . DS . $class . '.class.php');
} else if (file_exists(ROOT_PATH . DS . 'site' . DS . 'model' . DS . $class . '.class.php')) {
require_once(ROOT_PATH . DS . 'site' . DS . 'model' . DS . $class . '.class.php');
} else{
throw new Exception('Class `' . $class . '` could not be loaded!');
}
}
Every class it should load, is loaded. If I want to create a class which doesn't exist, then it throws an exception.
But with the pcu2phmmr6pam3 'classes' neither is the case. No exceptions were thrown, and now errors were printed on the screen, even though I've set error_reporting(E_ALL)
Here's the surrounding code of is_callable():
$controllerName = ucfirst($this->structure) . 'Controller';
$action = strtolower(((!empty($this->uri[1]))?$this->uri[1]:'index'));
if (is_callable(array($controllerName, $action))) {
$controller = new $controllerName($this->uri, $this->database, $this->structure, $action, $page);
$controller->$action();
} else if (is_callable(array($controllerName, 'index'))) {
$controller = new $controllerName($this->uri, $this->database, $this->structure, 'index', $page);
$controller->index();
} else {
$controller = new NotfoundController($this->uri, $this->database, 'Notfound', 'index', $page);
$controller->index();
}
Last bit of information I can give you:
My localhost xampp server runs PHP 5.4.7, and my host server runs PHP 5.3.20.
Solved, not sure how the weird classnames appeared, if someone knows, I'd like to know why :)
I had a similar problem calling a static method. (same with spl_autoload_register())
function __autoload ($className) {
echo $className."\n";
}
class ClassName {
function functionName () {
}
}
//calls __autoload twice with class name 'a22h1pd_t'
is_callable( array('ClassName', 'functionName') );
//doesn't call __autoload
is_callable('ClassName::functionName');
Looking at this minimal example it's obvious. The static keyword for functionName is missing. Adding it resolved the problem for me with both syntaxes behaving as expected.

Points for members in a network who invites non users

I have created a rule in Jomsocial to award points for member who invites non users.. But now the problem is that...The points are awarded even
when the member enters "invite friends" page
points awarded when member sent email to a user(never checks whether user is a member in network or not)
How can I restrict this?
I need to award points only when the email is sent to a "non-user" or when the non-user clicks the link in the email body.
Currently this is used in components/com_community/libraries/mailq.php inside the function:
public function send( $total = 100 )
{
$mailqModel = CFactory::getModel( 'mailq' );
$userModel = CFactory::getModel( 'user' );
$mails = $mailqModel->get( $total, true );
$jconfig = JFactory::getConfig();
$mailer = JFactory::getMailer();
$config = CFactory::getConfig();
$senderEmail = $jconfig->getValue('mailfrom');
$senderName = $jconfig->getValue('fromname');
The code below is used to award points. I think some more conditions need to be added to make it validated:
if($senderName)
{
$JomSocialCheck = JPATH_BASE . DS . 'components' . DS . 'com_community' . DS . 'libraries' . DS . 'userpoints.php';
if ( file_exists($JomSocialCheck)) {
include_once( JPATH_BASE . DS . 'components' . DS . 'com_community' . DS . 'libraries' . DS . 'userpoints.php');
CuserPoints::assignPoint('com_user.add.friend');
}
}
My grandpa used to say: "when you're shouting - I hear you, when you're talking - I'm listening..." ;)
One of the two problems, I believe you can solve by modifying your code as follows:
if($senderName)
{
$JomSocialCheck = JPATH_BASE . DS . 'components' . DS . 'com_community' . DS . 'libraries' . DS . 'userpoints.php';
if ( file_exists($JomSocialCheck)) {
include_once( JPATH_BASE . DS . 'components' . DS . 'com_community' . DS . 'libraries' . DS . 'userpoints.php');
$user =& JFactory::getUser();
if($user->id) {
// he's already a user - do nothing
}
else {
CuserPoints::assignPoint('com_user.add.friend');
}
}
}

Strange behaviour for spl_autoload on phpfog

I'm just trying to build my first app on PHP Fog but there's a piece of code that doesn't run properly - works fine on localhost and other regular hosts though.
I use a modified version of TinyMVC, this is the code responsible for setting up autoloading:
/* Set include_path for spl_autoload */
set_include_path(get_include_path()
. PATH_SEPARATOR . FRAMEWORK_BASEDIR . 'core' . DS
. PATH_SEPARATOR . FRAMEWORK_BASEDIR . 'libraries' . DS
. PATH_SEPARATOR . FRAMEWORK_APPLICATION . DS . 'controllers' . DS
. PATH_SEPARATOR . FRAMEWORK_APPLICATION . DS . 'models' . DS
);
/* File extensions to include */
spl_autoload_extensions('.php,.inc');
/* Setup __autoload */
$spl_funcs = spl_autoload_functions();
if($spl_funcs === false)
spl_autoload_register();
elseif(!in_array('spl_autoload',$spl_funcs))
spl_autoload_register('spl_autoload');
Basically, it fails at the first class it should load, which is located in "FRAMEWORK_BASEDIR . 'core' . DS". The class filename is "framework_controller.php" and class name is "Framework_Controller" (tried lowercase as well). If I include the class manually it works but fails with autoload.
Here's the error message that I get:
Fatal error: spl_autoload(): Class Framework_Controller could not be loaded in /var/fog/apps/app7396/claudiu.phpfogapp.com/application/controllers/home.php on line 12
Any ideas as to what could the problem be?
I managed to sort it out:
function framework_autoload($className, $extList='.inc,.php') {
$autoload_paths = array (
FRAMEWORK_BASEDIR . 'core' . DS,
FRAMEWORK_BASEDIR . 'libraries' . DS,
FRAMEWORK_APPLICATION . DS . 'controllers' . DS,
FRAMEWORK_APPLICATION . DS . 'models' . DS
);
$ext = explode(',',$extList);
foreach($ext as $x) {
foreach ($autoload_paths as $v) {
$fname = $v . strtolower($className).$x;
if(#file_exists($fname)) {
require_once($fname);
return true;
}
}
}
return false;
}
spl_autoload_register('framework_autoload');
Thanks to another question here on StackOverflow: spl_autoload problem

Categories