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
Related
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.
I am trying to create a zip file with folders inside it.
Now the code is :
{
$zipper = new \Chumper\Zipper\Zipper;
$zipper->make(storage_path('app/' . $zipPath));
.
.
Storage::makeDirectory($zipPath . DIRECTORY_SEPARATOR . $user->username , 0777);
$zipper->folder($zipPath . DIRECTORY_SEPARATOR . $user->username);
$currentZipPath = $zipPath . DIRECTORY_SEPARATOR . $user->username;
Storage::makeDirectory($currentZipPath . DIRECTORY_SEPARATOR . $myfolder->name , 0777);
$zipper->folder($currentZipPath . DIRECTORY_SEPARATOR . $myfolder->name);
.
.
$this->addDataToZip($contents, $currentZipPath . DIRECTORY_SEPARATOR . $myfolder->name, $zipper, $user);
Log::info('Zip status : ' . $zipper->getStatus()); //Gives "No error"
$zipper->close();
}
public function addDataToZip($contents, $path, &$zipper, $user)
{
foreach ($contents as $content) {
$filebasepath = storage_path('app/' . $path);
Storage::copy(
$this->model->getActiveStorageBasePath($user)
. DIRECTORY_SEPARATOR . $content->unique_name,
$path . DIRECTORY_SEPARATOR . $content->unique_name
);
$zipper->add(storage_path() . DIRECTORY_SEPARATOR . 'app'
. DIRECTORY_SEPARATOR . $path
. DIRECTORY_SEPARATOR . $content->unique_name);
}
}
Now when I view the folder locally, the entie admin.zip folder is created with complete heirarchy and content.
But on $zipper->close, the zip file is not created and the admin.zip folder remains there.
Also there is no error in the API call or the logs.
Please guide on where I might be making an error
See with example Chumper/Zipper. This is the simple and straightforward way to use.
OR you can place this line "status ::". $zipper->status . "\n" after $zipper->add() to check status.
I just want to know if I can create Product block in local code pool (i.e. \app\code\local\Mage\Catalog\Block\Product.php) without making my custom module just place this single file?
If so, will this local code pool block call or the core one call? If it would be the local one, please let me know why.
If you copy a code/core file to the code/local repository, the core file will be overwritten by the local file.
This is because of the include path order to load system files specified in app/Mage.php:
$paths = array();
$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';
So in your case the system will search for the Product.php in following order:
app/code/local/Mage/Catalog/Block/Product.php
app/code/community/Mage/Catalog/Block/Product.php
app/code/core/Mage/Catalog/Block/Product.php
lib/Mage/Catalog/Block/Product.php
If the system cannot find any of these files, it will throw an error.
Right so i'm making a configuration class that will use an array of different file types in 4 main locations. Now I want to make it so that the configuration class will search these locations in order at the moment i'm using the following
if (file_exists(ROOT . DS . 'Application/Config/' . APP_ENV . DS . $file)) {
$this->filePath = ROOT . DS . 'Application/Config/' . APP_ENV . DS . $file;
echo $this->filePath;
} else {
if (file_exists(ROOT . DS . "Application/Config/$file")) {
$this->filePath = ROOT . DS . "Application/Config/$file";
echo $this->filePath;
} else {
if (file_exists(CARBON_PATH . 'Config' . DS . APP_ENV . DS . $file)) {
$this->filePath = CARBON_PATH . 'Config' . DS . APP_ENV . DS . $file;
echo $this->filePath;
} else {
if (file_exists(CARBON_PATH . "Config/$file")) {
$this->filePath = CARBON_PATH . "Config/$file";
echo $this->filePath;
} else {
throw new \Exception("Unable to locate: $file, Please check it exists");
}
}
}
}
pretty messy and not very flexible.
What I want to be able to do is search the locations in the same order BY FILE NAME ONLY after finding the first match It would then return the file with the extension for the configuration class to use the correct method to parse into a php array and so on.
What is the best way to search these locations for a file name
Example
Say we want a database configuration file as you can see there are 2
ConfigLocation1/Dev/
/file.php
/database.json
ConfigLocation1/
/database.ini
/anotherfile.json
I would want to use the function like so
config::findFile('database');
and it return
$result = ConfigLocation1/Dev/database.json
but if it wasnt found here then then
$result = ConfigLocation1/database.ini
Not very good at explaining things so hope the example helps
As you mentioned you need to check for file in 4 locations, so instead of if conditions, create an array of directories and loop through.
and you can use glob, to find a file irrespective of extension. see my example below:-
//Make a array of directory where you want to look for files.
$dirs = array(
ROOT . DS . 'Application/Config/' . APP_ENV . DS,
CARBON_PATH . 'Config' . DS . APP_ENV . DS
);
function findFiles($directory, $filename){
$match = array();
foreach ($directory => $dir) {
$files = glob($dir.$filename);
foreach ($files as $file) {
$match[] = $file;
}
}
return $match;
}
// to find database
$results = findFiles($dirs, 'database.*');
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.