Is it possible to init AdminController from outside Prestashop? - prestashop

I am trying to initiate the AdminController module from outside the Prestashop. Basically, I am creating an external program which uses Prestashop to get current employee for which I should instantiate the AdminController, but its throwing error.
Many modules init the FrontController but I cannot find any example for AdminController like :
include(dirname(__FILE__).'/../../config/config.inc.php');
include(dirname(__FILE__).'/../../init.php');
Please advice.

I found the solution after all. Simply define _PS_ADMIN_DIR_ and init the config.inc.php, Prestashop will automatically load the admin environment. However, if you are loading this from a module, its tricky to find the admin directory as its not defined anywhere, so I have written this small script.
$admindir = '';
foreach (glob("../../*/ajaxfilemanager", GLOB_ONLYDIR) as $filename) {
$admindir = str_replace('../../', '', $filename);
$admindir = str_replace('/ajaxfilemanager', '', $admindir);
}
define('_PS_ADMIN_DIR_', getcwd().'/../../'.$admindir);
require(_PS_ADMIN_DIR_.'/../config/config.inc.php');
Enjoy!

Related

Prestashop LOG: get DUMP of Object and Array

I am figuring out how Prestashop 1.7 works and I have some experience with Symfony.
In Symfony development mode [Symfony project url]/_profiler is useful, among other things, to check the dump($someVariable) of variables in a request.
With Prestashop 1.7 in the admin mode it is possible to do [Prestashop project url]/admin[some random chain of chars]/_profiler to display the Symfony _profiler and analyse what's going on in the requests concerning the admin mode.
But if outside the admin mode (in the virtual shop demo mode), [Prestashop project url]/_profiler or [Prestashop project url]/[language value]/_profiler does not display the Symfony _profiler.
I have tried Prestashop own profiler by activating define('_PS_DEBUG_PROFILING_', true); in [prestashop project]/config/defines.inc.php. It displays Prestashop profiler at the bottom of the "virtual shop demo mode" but this one does not include dump($someVariable) that could be used, for development and to understand Prestashop behaviour, in a hookAction[action name].
I've managed to get the Symfony dump($someVariable) with hookDisplay[display name] through the HTML generated but not in a hookAction[action name] which is what I am looking for.
UPDATE
Looking at Prestashop 1.7 code I almost have the feeling that Symfony is only used on the Admin side, because I can see:
$kernel = new AppKernel(_PS_MODE_DEV_?'dev':'prod', _PS_MODE_DEV_); in [Prestashop project url]/admin[some random chain of chars]/index.php but I don't see it in [Prestashop project url]/index.php.
Best solution I've found so far is to create a custom logger similar to the one explained here
I've created file: [Prestashop project]/modules/[my module]/classes/CustomLogger.php
<?php
class CustomLogger {
const DEFAULT_LOG_FILE ="prestashop_system.log";
public static function log($message, $level = 'debug', $fileName = null){
$fileDir = _PS_ROOT_DIR_ . '/log/';
$fileName=self::DEFAULT_LOG_FILE;
if(is_array($message) || is_object($message)){$message = print_r($message, true);}
$formatted_message=$level." -- ".date('Y/m/d - H:i:s').": ".$message."\r\n";
return file_put_contents($fileDir . $fileName, $formatted_message, FILE_APPEND);
}
}
?>
In '[Prestashop project]/modules/[my module]/[my module].php' it is declared at the top:
include_once dirname(__FILE__).'/classes/CustomLogger.php';
And use CustomLogger::log($[some variable]); in your code.

How can I get the Register form on the front page in Drupal 8?

I've been trying to get the create account form (register form) in a pop-up on the front page, without any success.
Can anybody here help me out with an example that works?
I've tried adapting examples from Drupal 7 but couldn't get them to work, I've tried to make a custom form but it didn't work, I've tried installing modules that could handle this but they also didn't work.
The last attempt I've made to resolve this problem was:
<?php
/**
* #file
* Functions to support theming in the themename theme.
*/
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Utility\UrlHelper;
/**
* Implements hook_preprocess_HOOK() for HTML document templates.
*/
function themename_preprocess_html(&$variables) {
$form = \Drupal::formBuilder()->getForm('Drupal\user\register');
return $form;
}
Any help would be greatly appreciated.
Thank you!
you can use this module: https://www.drupal.org/project/formblock which exposes some additional forms as blocks (like the user registration, new password, contact, etc..). So after you install it you can just configure the block to appear only on the front page. The registration block will not be available for authenticated users or if the anonymous users are not allowed to create new accounts.
However, you will also have to apply this patch https://www.drupal.org/node/2570221 (if it will not be already committed by the time you check it) if you use the latest Drupal8 stable version, otherwise you will get a fatal error.
This link explains how it can be used to programmatically render the login and registration forms.
http://web-tricks.org/content/how-render-user-login-form-and-user-register-form-drupal-8
For the login form
$form = Drupal::formBuilder()->getForm(Drupal\user\Form\UserLoginForm::class) ;
$render = Drupal::service('renderer');
$variables['login_form'] = $render->renderPlain($form);
and for register form
$entity = \Drupal::entityTypeManager()->getStorage('user')->create(array());
$formObject = \Drupal::entityTypeManager()
->getFormObject('user', 'register')->setEntity($entity);
$form = \Drupal::formBuilder()->getForm($formObject);
$variables['register_form'] = \Drupal::service('renderer')->render($form);

Codeception Cept tests _bootstrap variables

Codeception default _bootstrap.php file states:
<?php
// Here you can initialize variables that will be available to your tests
So I wanted to initialize a variable inside of it:
<?php
$a = 5;
However, when I use it my SomeAcceptanceCept:
<?php
// ....
$I->fillField('description', $a);
I get: ErrorException: Undefined variable: a
I did var_dump in _bootstrap.php and it indeed get's ran once before acceptance tests, but variables from it are not available in my tests.
I can't seem to find any documentation on this.
I'm actually trying to initialize Faker instance to use in my tests.
I find the documentation on this to be quite confusing. I was attempting to do the exact same thing to no avail. So I ended up using Fixtures by putting this in the _bootstrap.php file:
use Codeception\Util\Fixtures;
use Faker\Factory;
$fake = Factory::create();
Fixtures::add('fake', $fake);
(You could also use a separate fixtures.php file and include it in your test.)
Which allows you to get the faker object or anything else like this:
Fixtures::get('fake');
The strange thing is that if you look at the Fixtures docs it actually mentions using the Faker library to create tests data in the bootstrap file.
I do the following:
// _bootstrap.php
$GLOBALS['a'] = 5;
Then within my tests I call it like so:
// MyCest.php
public function testItWorks(\Tester $I)
{
global $a;
$I->fillField('description', $a);
}
I haven't done much work with Cept files but probably something similar will work.
Define it like this in your bootstrap.php :
<?php
// This is global bootstrap for autoloading
define("email", "someone#abc.com");
define("password", "my_secure_pass")
Use it like this:
public function testValidLogin(AcceptanceTester $I)
{
$I->fillField(loginPage::$username, email);
$I->fillField(loginPage::$password, password);
$I->click("LOG IN");
}
NOTE: no dollar signs. use as only as 'email' and 'password'
I dumped all PHP variables and confirmed that any variables set in the _bootstrap.php file do not exist and are not available in the MyCept.php file. So I resorted to adding the following at the top of MyCept.php:
include '_bootstrap.php';
This makes the variables set in _bootstrap.php available. Of course.

Using Db::getInstance() in a CLI script

I've been wanting to create a add-on cron script that utilises Prestashop's DB class instead of instantiating the database handle directly, but I can't seem to figure out where did the "Db" class commonly referenced by "Db::getInstance()" calls get defined.
classes/Db.php defines an abstract DbCore class. MySQLCore extends Db as you can see, however Db is never defined anywhere:
[/home/xxxx/www/shop/classes]# grep -r "extends Db" ../
../classes/MySQL.php:class MySQLCore extends Db
According to another thread on Prestashop forums, the abstract DbCore class is implemented in a class located in override/classes/db, however that directory does not exist.
[/home/xxxx/www/shop/override]# cd ../override/
[/home/xxxx/www/shop/override]# ls
./ ../ classes/ controllers/
[/home/xxxx/www/shop/override]# cd classes/
[/home/xxxx/www/shop/override/classes]# ls
./ ../ _FrontController.php* _Module.php* _MySQL.php*
Our shop is working, so obviously I am missing something. We are running Prestashop 1.4.1, so perhaps the docs are no longer applicable.
Quite clearly in many places in the code base functions from the Db class are being used, but this last grep through the code found nothing:
grep -rwI "Db" . | grep -v "::"
./modules/productcomments/productcommentscriterion.php:require_once(dirname(__FILE__).'/../../classes/Db.php');
./classes/MySQL.php:class MySQLCore extends Db
./classes/Db.php: * Get Db object instance (Singleton)
./classes/Db.php: * #return object Db instance
./classes/Db.php: * Build a Db object
Is there something I am missing? Where did this magical Db class come from?
To create a CLI script, the easiest way is to include the config file so you will have access to every classes. For example
<?php
require dirname(__FILE__).'/config/config.inc.php'; // assuming your script is in the root folder of your site
// you can then access to everything
$db = Db::getInstance();
You are confused a little bit with this. In PS 1.4.x. in the override directory, no files are palced. The documentation is following PS 1.5.x.
PS is using autoload feature to load classes. Lets take DB class as an example. The file name is Db.php , but class name is DbCore and when we want to get object of Db class, we do it like
Db::getInstance();
means not like
DbCore::getInstance();
How this works ? The thing is the php auto load function. Checkout the config/autoload.php (or a file with a name like that), and you will see that PS checking the class with and without Core at the end of the class name. Means that if the a name has Core or not, it will be loaded.
Starting with PS 1.5.x , PS placed over rided files in override/classes folder. Please note that all those classes are extending their respective classes. For example in override/classes/db the class Db.php is placed and this file has only the following code
<?php
abstract class Db extends DbCore
{
}
So it is clear if we want to use Db class, it will call the override/classes/db/Db.php which is extended from DbCore class.
Similarly for all other classes, the same criteria is used.
I hope those details will help.
Thank you

Yii generates error "Unable to resolve the request <controller/action>"

After logged in successfully, Yii does not executing any page.
Showing an error:
Error 404 Unable to resolve the request "membersdet/index"
Here membersdet is controller Id and index is an action.
Make sure the filename of your controller is EXACTLY "MembersdetController.php". It is case sensitive.
I guess you were developing on local machine under Windows OS and server runs on *nix system. That's normal issue for novice developers, that they forget about case sensitive file system in *nix.
It is because of wrong controller file name given or may be actionIndex() method is not in your controller.
I have had a similar problem and got it solved. In this case the file was correctly named but the class name was wrongly spelled. When these two do not correspond, you could get this error too.
Check case sensitive exactly your controller: MembersdetController
Check alias (common in config/main.php) map with namespace in your controller
Yii::setAlias('#tienn2t', dirname(dirname(__DIR__)) . '/tienn2t');
In MembersdetController.php file
<?php
namespace tienn2t\controllers;
use Yii;
use yii\web\Controller;
class MembersdetController extends Controller{
public function actionIndex(){
echo 1;die;
}
}
There is not enough information in the question, but maybe you have an incorrect .htaccess or if you don't have an htaccess at all you should use the url:
http://host/index.php?r=membersdet/index
Make sure you have MembersdetController in /protected/controllers/ and this class "is a" CController and has a public method named actionIndex().
Check errorHandler block in your config file.
I had fix this error like this
'errorHandler' => [
'errorAction' => 'error/index',
],
By the way you should have appropriate ErrorController in your module and /error/index.php
file in view folder.
Hope will help you.