Code:
public function init()
{
global $cookie, $smarty, $cart, $iso, $defaultCountry, $protocol_link, $protocol_content, $link, $css_files, $js_files;
if(!session_id()){
if(!isset($_SESSION)){
session_start();
}
}
$cookie->id_cart=$_SESSION['pj_punchout_id'];
if (self::$initialized)
return;
self::$initialized = true;
$css_files = array();
$js_files = array();
Error:
Strict Standards: Creating default object from empty value in C:\xampp\htdocs\pjwebstoredev\classes\FrontController.php on line 82
I'm assuming that you're using Prestashop v1.4. The main problem I can see is that you've edited one of the core files, so most bets are off for the ability to support your code in the future. If you want to cleanly modify the behaviour of the core classes, then you should create an override called /override/classes/FrontController.php with the following contents:
class FrontController extends FrontControllerCore
{
function init()
{
// Your additional custom init code goes here
parent::init();
// And/or additional custom init code goes here
}
}
That's not the fundamental problems though, as we get to the next stage. The error you're seeing is because you are tring to use the global variable $cookie, but at a point in time before the variable is set to anything meaningful (the global cookie variable is actually initialised later in the very function you were modifying). Since you need to manipulate the cookie properties then you could try creating a temporary cookie object, use it to manipulate the user's cookie, then call the core code e.g.
class FrontController extends FrontControllerCore
{
function init()
{
if ( !session_id() ) {
if( !isset($_SESSION) ) {
session_start();
}
}
$cookieLifetime = (time() + (((int)Configuration::get('PS_COOKIE_LIFETIME_FO') > 0 ? (int)Configuration::get('PS_COOKIE_LIFETIME_FO') : 1)* 3600));
$cookie = new Cookie('ps', '', $cookieLifetime);
$cookie->id_cart=$_SESSION['pj_punchout_id'];
parent::init();
}
}
Related
I have a custom content type called "program" that I am trying to load via a drupal module.
The .module file includes a class called Program that has a method called
getAllPrograms() using include_once(drupal_get_path('module', 'progs') . '/progs.php');
When i try and load nodes using either node_load() or node_load_multiple() i get one of two different errors randomly.
either:
Fatal error: Fatal error: Call to undefined function user_access() in /mypath/modules/filter/filter.module on line 1035
or
Error: Call to undefined function token_get_entity_mapping() in /mypath//sites/all/modules/contrib/token/token.tokens.inc, line 767
Note: 99% of times it is the first error, and occasionally i would recieve the token_get_entity error.
The strange thing is, while i have been trying different things to resolve the error I have been able to get both of these functions to work for a period but as soon as i clear the Drupal Cache i get the error again.
What I have tried
Disabling and enabling the user module via the database.
Checking the paths and status are correct for the main modules (system, user, block etc)
using db_select to get a list of node ids and then use node_load() (with a loop) and node_load_multiple() to load the nodes. This is one of the things that started working for a short time until i cleared the cache.
Tested to see if i can call user_access() from my .module file. This does not work and returns the same call to undefined function error.
Here is the code that I have (not progs an anonymized name)
progs.module
include_once(drupal_get_path('module', 'progs') . '/progs.php');
progs.php
if( !class_exists('progs') ):
class progs
{
//a bunch of properties
function __construct()
{
// load partial includes and objects
$this->load_partial_inclues();
//retrieve all programs that are open
$this->open_programs = Program::getAllOpenPrograms();
}
function load_partial_inclues()
{
//includes
include_once(drupal_get_path('module', 'progs') . '/core/objects/program.php');
}
}
function progs()
{
global $progs;
if( !isset($progs) )
{
$progs = new progs();
}
return $progs;
}
// initialize
progs();
endif;
Note: I load the $progs into the global space so i can call it elsewhere in my module.
program.php
if( !class_exists('Program') ):
class Program
{
//a bunch of properties
public static function getAllOpenPrograms()
{
// This is the line that causes all of the issues.
$result = node_load_multiple('',array('type' => 'program'));
dpm($result);
}
Thanks in advance!
Like Mike Vranckx mentioned, if you call progs() directly when you include it in progs.module, Drupal basically hasn't bootstrapped, i.e. hasn't started running fully yet. Suggest you put your progs() in progs_init() or similar so that Drupal will invoke it at the right time.
Here's a proposed way that follows your initial structure quite closely, and below you will see an alternative that better follows Drupal's conventions.
New progs.module
/**
* Implements hook_init().
*/
function progs_init(){
progs();
}
And modify your progs.php
// Why are you doing this check? Are you defining this class elsewhere in your project? If not you can safely ignore this
//if( !class_exists('progs') ):
// Convention is to name classes with Pascal case btw.
class progs
{
//a bunch of properties
function __construct()
{
// load partial includes and objects
$this->load_partial_inclues();
//retrieve all programs that are open
$this->open_programs = Program::getAllOpenPrograms();
}
function load_partial_inclues()
{
//includes
include_once(drupal_get_path('module', 'progs') . '/core/objects/program.php');
}
}
function progs()
{
global $progs;
if( !isset($progs) )
{
$progs = new progs();
}
return $progs;
}
A more Drupal way:
progs.module
/**
* Implements hook_init().
*/
function progs_init(){
global $progs;
// Consider using drupal_static to cache this
if( !isset($progs) )
{
module_load_include('inc', 'progs', 'progs');
$progs = new Progs();
}
}
progs.inc (convention is to use .inc)
class Progs
{
//a bunch of properties
function __construct()
{
// load partial includes and objects
$this->load_partial_inclues();
//retrieve all programs that are open
$this->open_programs = Program::getAllOpenPrograms();
}
function load_partial_inclues()
{
//includes
module_load_include('php', 'progs', 'core/objects/program');
}
}
I'm having a problem loading modules inside my template library in CodeIgniter HMVC. The reason I want to load a module in the template library is that I wish to use modules for sideboxes and other content boxes in my template.
PS: I am also using the Smarty template parsing system for CodeIgniter, but I doubt it has anything to do with the errors, but if you have reasons to believe otherwise, please, let me know.
What I tried to do
I tried to load the module in two different ways, and both presented with the same errors.
The errors
A PHP Error was encountered
Severity: Notice
Message: Undefined Property CI::$template
File: MX/Loader.php
Line Number: 141
-
A PHP Error was encountered
Severity: Notice
Message: Undefined Property CI::$template
Filename: MX/Controller.php
Line number: 57
-
Fatal error: Call to a member function load_content() on a non-object in E:\Xampp\htdocs\firecms\application\modules\sidebar_login_box\controllers\sidebar_login_box.php on line 7
The undefined "load_content()" function will be explained further down (in Sidebar Controller).
The Error lines
MX/Loader
/*Line 140*/if (isset($this->_ci_classes[$class]) AND $_alias = $this->_ci_classes[$class])
/*Line 141*/ return CI::$APP->$_alias;
MX/Controller
/*Line 56*/public function __get($class) {
/*Line 57*/ return CI::$APP->$class;
How I tried to load the modules
This was my first attempt (loading the file and instancing its class):
class Template {
//[...]
public function load_sidebars()
{
$sidebars = $this->CI->cms_model->get_sidebars();
foreach ($sidebars as $sidebar)
{
if (trim($sidebar["content"]) == "")
{
//An example of sidebar module name is "sidebar:login_box"
//The function below changes the name to "sidebar_login_box" (the
//module's folder and controller name.
$module = str_replace(':', '_', $sidebar["module"]);
$file_path = APPPATH.'modules/'.$module.'/controllers/'.$module.'.php';
require_once $file_path;
$class = ucfirst($module);
$object = new $class();
$module_data = $object->index();
$this->_section_data["sidebars"][]["content"] = $module_data;
}
else
{
$this->_section_data["sidebars"][]["content"] = $sidebar["content"];
}
}
}
//[...]
}
And this was my second attempt (using the loader function):
public function load_sidebars()
{
$sidebars = $this->CI->cms_model->get_sidebars();
foreach ($sidebars as $sidebar)
{
if (trim($sidebar["content"]) == "")
{
$module = str_replace(':', '_', $sidebar["module"]);
$this->CI->load->module($module);
$module_data = $this->CI->$module->index();
$this->_section_data["sidebars"][]["content"] = $module_data;
}
else
{
$this->_section_data["sidebars"][]["content"] = $sidebar["content"];
}
}
}
The sidebar controller
This is how the sidebar controller looks like:
class Sidebar_login_box extends Fire_Controller {
public function index()
{
$view_data = array();
//The load_content function in the template library is used to parse template files
//and return them as a string.
return $this->template->load_content("login_box", $view_data);
}
}
The Fire Controller
The Fire_Controller is my core controller. My core classes' prefix is Fire_ instead of MY_.
This is how the fire controller looks like:
class Fire_Controller extends MX_Controller {
public function __construct()
{
parent::__construct();
//Load configurations from the database.
$this->config->load_db_configs();
//Set the timezone.
date_default_timezone_set(config_item("timezone"));
//Loads the form validation library.
$this->load->library("form_validation");
//Reset the Form Validation CI Object (to fix problems with HMVC CI).
$this->form_validation->CI =& $this;
//To reduce load time, the template library will not be loaded in ajax
//requests.
if ( ! $this->input->is_ajax_request())
{
$this->load->library("template");
}
//Force access via SSL connection (HTTPS) if necessary.
if ((int)config_item('force_https') === 1)
{
force_https();
}
}
Note: This is a very recent project of mine, which means that the framework and all third party extensions are in the most recent stable version as of January 06, 2015.
Thank you for your time,
Best regards.
Fixed.
The sidebars were loaded from the set_defaults() method, which was called by the constructor method in my template library. And since it wasn't fully loaded, the template object was not saved in CI's super object, thus being inaccessible and throwing the errors in the sidebar module.
I have moved the set_defaults() call to the render_page() function of my template library (which are called by the modules' controllers), and now it's working perfectly.
Too bad I added bounty a few hours before finding the solution, hehe.
You need to load the library before you can use it in the sidebar controller. It isn't being passed from the parent. Try this:
class Sidebar_login_box extends Fire_Controller {
public function index()
{
$view_data = array();
$this->load->library('template');
//The load_content function in the template library is used to parse template files
//and return them as a string.
return $this->template->load_content("login_box", $view_data);
}
}
Cheers!
I have the following code in my zend application bootstrap file
protected function _initSessionId() {
$this->bootstrap( 'session' );
$opts = $this->getOptions();
$cache = $this->bootstrap( 'cachemanager' )
->getResource( 'cachemanager' )
->getCache( 'memcached' );
Zend_Db_Table_Abstract::setDefaultMetadataCache( $cache );
Zend_Registry::set( 'cache', $cache );
$defaultNamespace = new Zend_Session_Namespace();
if ( !isset( $defaultNamespace->initialized ) ) {
Zend_Session::regenerateId();
$defaultNamespace->initialized = true;
}
}
I want to know what the line $this->bootstrap('session') actually does. Which class/function does it instantiate and call?
How to bootstrap a resource
bootstrap(<resource_name>) tells to Zend_Bootstrap to init the specified resource before continue. Usually is used for init required dependencies before init the actual resource
The resource bootstrap can be declared in two ways.
A PHP method in the Bootstrap class.
function _init<Resource_name>() { ... }
Or in the ini file
resources.<resource_name>
in the last case (ini file) a class extending from Zend_Application_Resource_ResourceAbstract must be declared with the code for init the resource.
Session resource bootstrap
For the concrete case of bootstrap('session') by default use the init() method declared in Zend_Application_Resource_Session
I'm experimenting with php mvc and I'm stucked with the following issue. My request and router classes are really simple and I would like to extend theme to can handle controller calls from sub folders and to controller classes functions should be able to pick up url variables send it threw get and post.
my router looks as it follows
class Router{
public static function route(Request $request){
$controller = $request->getController().'Controller';
$method = $request->getMethod();
$args = $request->getArgs();
$controllerFile = __SITE_PATH.'/controllers/'.$controller.'.php';
if(is_readable($controllerFile)){
require_once $controllerFile;
$controller = new $controller;
if(!empty($args)){
call_user_func_array(array($controller,$method),$args);
}else{
call_user_func(array($controller,$method));
}
return;
}
throw new Exception('404 - '.$request->getController().'--Controller not found');
}
}
and Request class
private $_controller;
private $_method;
private $_args;
public function __construct(){
$parts = explode('/',$_SERVER['REQUEST_URI']);
$this->_controller = ($c = array_shift($parts))? $c: 'index';
$this->_method = ($c = array_shift($parts))? $c: 'index';
$this->_args = (isset($parts[0])) ? $parts : array();
}
public function getController(){
return $this->_controller;
}
public function getMethod(){
return $this->_method;
}
public function getArgs(){
return $this->_args;
}
}
The problem is:when I try to send threw ajax, variables to a controller method this are not recognized because of its url structure.
For example
index/ajax?mod_title=shop+marks&domain=example
is accepted just if it look
index/ajax/shop+mark/example
Your code contains what is known as an LFI vulnerability and is dangerous in its current state.
You should whitelist your what can be used as your $controller, as otherwise an attacker could try to specify something using NUL bytes and possibly going up a directory to include files that SHOULD NOT be ever included, such as /etc/passwd, a config file, whatever.
Your router is not safe for use; beware!
edit: example on whitelisting
$safe = array(
'ajax',
'somecontroller',
'foo',
'bar',
);
if(!in_array($this->_controller, $safe))
{
throw new Exception(); // replace me with your own error 404 stuff
}
Since your Request class uses a URI segments approach for identifying controller, action and arguments, global variables such as $_GET or $_REQUEST are not taken into account from within your Request.
What you need to do is to make some additions to your Request code. Specifically:
Remove the line:
$this->_args = (isset($parts[0])) ? $parts : array();
And add the following:
$all_parts = (isset($parts[0])) ? $parts : array();
$all_parts['get'] = $_GET;
$this->_args = $all_parts;
This way, $_GET (ie variables passed via the url) variables will be available in the actions called, as they will be in $args (they will be available as $args['get'] actually, which is the array that holds the $_GET vars, so you will be able to have access to domain=example by using $args['get']['domain']).
Ofcourse, you can add one more method in your Request class (e.g. query) that might look like that:
public function query($var = null)
{
if ($var === null)
{
return $_GET;
}
if ( ! isset($_GET[$var]) )
{
return FALSE;
}
return $_GET[$var];
}
This way, you can get a single variable from the url (e.g. $request->query('domain')) or the whole $_GET array ($request->query()).
That's because php will put "?mod_title=..." in the $_GET array automatically. Your getArgs() function should check for $_GET, $_POST or $_REQUEST.
If you're trying for a minimal MVC approach, have a look at rasmus' example: http://toys.lerdorf.com/archives/38-The-no-framework-PHP-MVC-framework.html
If your use case is going to get more complex, have a look at how Zend (http://framework.zend.com/manual/en/zend.controller.html) or Symfony (https://github.com/symfony/symfony/tree/master/src/Symfony/Component/Routing) do their stuff.
Choose any popular MVC to see how they implement it under the hood. In addition, spl_autoload_register and namespace are your friends.
I need to have some configuration options on my website.
I thought it would be easiest to maintain if different options are placed in different files.
Also I need to have a class to retrieve the options from different configuration files.
In the directory structure of my website I created a directory called /setup
In this directory I have several files for the different configuration options, eg: /setup/base.php
The contents of base.php will look something like the following:
$setup = new stdClass();
$setup->currencies = array('USD', 'EUR', );
$setup->locations = array('local', 'international', );
I would like to create a class which reads the file and returns the different options.
class Options
{
function __construct($option)
{
if (!is_file(SETUP_DIR.'/'.$option.'.php')) {
thrown new Exception('Configuration file not found.');
}
$options = // get information from file
return $options; // this should return the currencies and locations
}
}
$options = new Options('base');
However I don't know whether this is the correct way of doing it.
If so I cannot think of a way to retrieve the options from the setup files in the class.
Can you help me with this or at least point me in the right direction?
Well, I don't think there is a right way for this one: Zend uses .ini files, Codeigniter has a set of arrays, and Symfony uses YAML. Wordpress stores most everything in the database, and has one config file which it just includes.
Personally, I'm partial to ini files -- ini is something which is used all over the place, so it has a feeling of, "I can reuse this if necessary", but I think that the only "wrong" solution here is one which is inconsistent -- if you're using ini, use ini, if arrays, arrays, but don't mix.
In your case, there are a couple of options. These two seem to be among the most common. (both of these examples assumes that the stdClass object is named $options in the loaded file) You could create a wrapper:
class Options
{
private $_options;
function __construct($option)
{
if (!is_file(SETUP_DIR.'/'.$option.'.php')) {
thrown new Exception('Configuration file not found.');
}
require(SETUP_DIR.'/'.$option.'.php');
$this->_options = $options;
// you shouldn't put a return in a constructor
}
// this will point to the internal _options variable.
// making it a read-only access to the values from $option
public function __get($name){ return $this->_options->$name; }
}
Or, you could use a Singleton pattern and just return the objects in the individual classes:
class OptionsRetriever
{
private $_fetched;
private static $_instance;
private __construct(){}
public static function &getInstance()
{
if( !isset( self::$_instance ) ) self::$_instance = new OptionsRetriever();
return self::$_instance;
}
public function getConfig( $name )
{
if( !isset( $this->_fetched[ $name ] ) )
{
require(SETUP_DIR.'/'.$name.'.php');
$this->_fetched[ $name ] = $options;
}
return $this->_fetched[ $name ];
}
}
Or, you could combine them:
class Options
{
private $_options;
function __construct($options)
{
$this->_options = $options;
}
public function __get($name){ return $this->_options->$name; }
}
// replace getConfig with this
public function getConfig( $name )
{
if( !isset( $this->_fetched[ $name ] ) )
{
require(SETUP_DIR.'/'.$name.'.php');
$this->_fetched[ $name ] = new Options( $options );
}
return $this->_fetched[ $name ];
}
You can use the concept of ini files and the parse_ini_file function in PHP to accomplish this. There are clear examples on the php.net function page: parse_ini_file # PHP.NET
You could just include the base.php file, like so:
class Options
{
function __construct($option)
{
if (!is_file(SETUP_DIR.'/'.$option.'.php')) {
thrown new Exception('Configuration file not found.');
}
include_once(SETUP_DIR.'/'.$option.'.php');
$options = $setup; // make sure your variable in the config is allways named $setup
return $options; // this should return the currencies and locations
}
}
$options = new Options('base');
echo $options->currencies[0]; //should print 'USD' provided that your base.php file from the question was used.
If you wan't the values stored in PHP directly you would need to include PHP files with the values in them, for instance as variables, constants or classes.
A method i like to use is storing configuration in an XML file and then loading and parsing that. Same method could be used with JSON if you prefer that format. Just make sure you block any browser access to those files.