Using prestashop app from script located outside prestashop folder - prestashop

I would like to use the prestashop app from a php script (external_script.php) located outside prestashop folder but still on the same server.
I could do that with Magento using :
require_once external_folder/magento/app/Mage.php;
I've tried to include prestashop/config/config.inc.php and prestashop/init.php but it redirects external_script.php to prestashop index.php
Any help would be greatly appreciated.
STEF

Add the following 2 lines at the start of your PHP script and then you can use all the classes and functions of PrestaShop:
include(dirname(__FILE__).'/../../config/config.inc.php');
include(_PS_ROOT_DIR_.'/init.php');
Also, include the main class file whose functions you want to call in the external script, it must be some of your module's file. For example:
include_once(__PATH__TO__CLASS__FILE__.'/xyzmodule.php');
After adding the above codes to include required files you can simply create objects of the class file you want to call and use its code. For example:
$xObj = new Xyzmodule();
$xObj->callingXFunction();
Hope this helps.

Magento is a well structured Zend project and it's easy to bootstrap the app to use it outside HTTP front controller, PrestaShop is another story it's really a big mess of spaghetti code, to bootstrap the app really depends os PS version and in some cases on installed modules that changes core behaviour.
To start you can first include the config/config.inc.php file that is on PS root dir, this will init the PS classloader and a bunch of configuration defines, if you use another autoloader and a old version on PS (<1.6) you need to workaround it, this is a simple bootstrap code that allow make any PS call:
<?php
// Load PS config and autoloader
define ('PS_DIR', __DIR__ . '/../ps-wtf');
require_once PS_DIR .'/config/config.inc.php';
// I use this to load compoper dependencies
require_once __DIR__ . '/../vendor/autoload.php';
// Call old __autoload() if present, required for PrestaShop old versions
if (function_exists('__autoload')) {
spl_autoload_register(function ($className) {
__autoload($className);
});
}
// Init Shop context, required some operation will fail without it
// adust accordly to multistore PS >= 1.6
Shop::setContext(Shop::CONTEXT_ALL);
// Init PS context, some modules require that this context was initialized and with correct data
// some core function fired in the admin require at least a employee
define ('PS_DEFAULT_EMPLOYEE', 1);
$psContext = Context::getContext();
if (!$psContext->employee) {
$psContext->employee = new Employee(PS_DEFAULT_EMPLOYEE);
}
// You can make any API call
$cat = new Category();
$cat->name = [
1 => 'New',
2 => 'Nuevo',
];
$cat->id_parent = 1;
$cat->save();
echo $cat->id;
Some PS functionality depends on correct initialization of some core classes (Yes it's crazy), you can take a look at ControllerCore and FrontControllerCore to see what is happening in the normal PS request flow.
I hope that this can help.

The way prestashop is designed won't let you do this kind of thing easily.
I think your best bet is to use their web service API : http://doc.prestashop.com/display/PS16/Using+the+PrestaShop+Web+Service
There is a PHP client library for this : https://github.com/PrestaShop/PrestaShop-webservice-lib/blob/master/PSWebServiceLibrary.php
You can also use curl, but be warned : they use a lot of different tokens on differents pages, this is quite annoying.
Here is some bash code to log yourself in, grab some tokens and upload an import file. You can adapt it to PHP curl and do anything else you want :
r=$(curl -k -c cookies -b cookies -s --request POST -d "ajax=1&token=&controller=AdminLogin&submitLogin=1&passwd=[YOU_PASSWORD_URL_ENCODED]&email=[YOUR_EMAIl_URL_ENCODED]" 'https://[YOUR_PRESTASHOP_HOST_OR_LOCALHOST]/[YOUR_PRESTASHOP_ADMIN_DIR]/index.php')
token=$(echo $r | sed -n 's/.*token=\([0-9a-zA-Z]*\).*/\1/gp')
admin_token=$(curl -k -c cookies -b cookies 'https://[YOUR_PRESTASHOP_HOST_OR_LOCALHOST]/[YOUR_PRESTASHOP_ADMIN_DIR]/index.php?controller=AdminDashboard&token='"$token" | sed -n '0,/.*?_token=\([-_0-9a-zA-Z]*\).*/s/.*?_token=\([-_0-9a-zA-Z]*\).*/\1/p')
brand_file_name=$(curl -k -c cookies -b cookies -F 'file=#local_path_of_a_file.xlsx' 'https://[YOUR_PRESTASHOP_HOST_OR_LOCALHOST]/[YOUR_PRESTASHOP_ADMIN_DIR]/index.php/configure/advanced/import/file/upload?_token='"$admin_token" | sed -nE 's/.*"name":"([^"]*).*/\1/gp')

Related

Failing authentication test, using Laravel, phpunit and Homestead

So, I'm trying to test the register and login features on a Laravel 5.8 project, running on Homestead.
My problem is that I can't get the tests (for login and for register) to pass the assertAuthenticated() and assertAuthenticatedAs() functions.
I created the login feature using php artisan make:auth and didn't changed a lot, just created a "username" field to use instead of email.
When I test things like assertStatus(), $this->get(url), everything works fine but when I add the line $this->assertAuthenticatedAs($user) for example, the test crashes.
This is my actual passing function:
public function test_login_valid_user()
{
$user = factory(User::class)->create();
$response = $this->post('/login', [
'username' => $user->username,
'password' => 'secret'
]);
$response->assertStatus(302);
}
If I add the line $this->assertAuthenticatedAs($user) at the end, I get the following error:
There was 1 failure:
1) Tests\Feature\Auth\LoginTest::test_login_valid_user
The current user is not authenticated.
Failed asserting that null is not null.
/home/vagrant/code/my_project/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithAuthentication.php:89
/home/vagrant/code/my_project/tests/Feature/Auth/LoginTest.php:39
The same is happening on my register test, after the user is registered, when I try to check $this->assertAuthenticated() I get the same error.
So, I thought about session problems related to Vagrant/Homestead, but I just started to use them and couldn't find any hint about it. And I'm very new to PHPUnit and testing in general, I'm just starting to understand how it works.
The problem is connected with caches.
First of all file phpunit.xml must be read because you need: <server name="APP_ENV" value="testing"/>
Before your tests use command
php artisan config:clear
After that your dump(config('app.env')); will be testing (not local).
Then all works.
I'd been experiencing same problem. For unit tests CSRF token verification should be disabled, but only if you are running under APP_ENV=testing. I though phpunit.xml was overriding my "local" config so it was set to "testing". It was not, because PhpStorm was not reading this file.
If you are using PHPStorm don't forget to check path to default config file - phpunit.xml. (Settings -> Languages&Frameworks -> PHP -> Test frameworks)

Laravel 5: Why Class 'App\Console\Commands\SSH' not found?

I'm following instructions on
https://laravelcollective.com/docs/5.1/ssh
in order to use SSH to perform SFTP download from a private server.
I've done so far:
$> composer require laravelcollective/remote
added in config app :
'providers' => [
....
Collective\Remote\RemoteServiceProvider::class,
...
]
'aliases' => [
....
'SSH' => Collective\Remote\RemoteFacade::class,
...
]
published it:
$> php artisan vendor:publish --provider="Collective\Remote\RemoteServiceProvider"
Then I also run a composer update
But still in my console command if I test it like:
$contents = SSH::into('production')->getString('/hi.txt');
dd($contents);
I get the error in my question.
When a service provider is defined like above, the class is globally accessible? Or still I need to put the directive use Path/to/Class ?
If so, since the Alias ahas a different name from the real classname, how should I specify the use path directive?
use Collective\Remote\RemoteServiceProvider
or
use Collective\Remote\RemoteServiceProvider
?
What am I missing?... I've tested other preconfigured services that comes with laravel 5.2 fresh install (i.e. Redis) and they seems to be found without any additional use directive in class.....
Thanks
Just use it as global class \SSH and it will work.
$contents = \SSH::into('production')->getString('/hi.txt');
dd($contents);

Composer needs a proxy to install laravel apparently, where do I get that? can I set it up myself using apache?

I was trying to get started with Laravel just last night, so I tried to install it with composer but it wouldn't go through and kept sayin The "https://packagist.org/packages.json" file could not be downloaded: SSL operation failed with code 1. , so I looked around and found out that you need to tell composer to use a proxy.(q1 q2 q3).
Well now this might sound silly but honestly I had no idea what a proxy was until last night, so I went and studied it a bit and I got this far:
"Proxy means to act on behalf of another. In the context of a Web server, this means
one server fetching content from another server, then returning it to the client"
and apparently there's 2 kinds of proxy: forward proxy and reverse proxy.
In those 3 pages that I just showed, they were saying before runing php bin\composer global require "laravel/installer=~1.1" you have to set an env var like this: set http_proxy=username:password#proxy_server:port
So now my question is: I still don't know where can I get a proxy like that, should I set it up myself with apache? is that gonna even work? what do I do?
Your thoughts would be appreciated, thank you.
Edit: Environment info:
I'm on windows 7
installed xampp-win32-5.6.14-0-VC11-installer
all of those 5 important extensions are all enabled in phpinfo()
the path= C:\Users\UserName\AppData\Roaming\Composer\vendor\bin is set in environment variables
here's a picture of the whole error
here's the result of php -m i.stack.imgur.com/wz030.png
Some stuff that I tried:
I went into these sites: proxy4free.com us-proxy.org proxylist.hidemyass.com ultraproxies.com,
I tried this: set https_proxy=https://xteamweb.com:xteam#75.55.165.86:8088 and this one: set http_proxy=http://1proxy.space and many others from those sites: i.stack.imgur.com/6YWyp.png
but no matter what, this is the result of all of them: i.stack.imgur.com/mqOrP.png
Still nothing...
Ok here's the solution, if you're having the same problem:
1:
Make sure these are all uncommented in php.ini:
extension=php_openssl.dll
extension=php_curl.dll
extension=php_sockets.dll
extension_dir="E:\xampp\php\ext"
browscap="E:\xampp\php\extras\browscap.ini"
Add these 2 lines at the end of php.ini
curl.cainfo=c:\openssl-1.0.2d-win32\ssl\cert.pem
openssl.cafile=c:\openssl-1.0.2d-win32\ssl\cert.pem
2:
Run this: php -r "print_r(openssl_get_cert_locations());"
and you'll get:
Array
(
[default_cert_file] => c:/openssl-1.0.2d-win32/ssl/cert.pem
[default_cert_file_env] => SSL_CERT_FILE
[default_cert_dir] => c:/openssl-1.0.2d-win32/ssl/certs
[default_cert_dir_env] => SSL_CERT_DIR
[default_private_dir] => c:/openssl-1.0.2d-win32/ssl/private
[default_default_cert_area] => c:/openssl-1.0.2d-win32/ssl
[ini_cafile] => c:\openssl-1.0.2d-win32\ssl\cert.pem
[ini_capath] =>
)
3:
Make these folders:
c:\openssl-1.0.2d-win32
c:\openssl-1.0.2d-win32\ssl
c:\openssl-1.0.2d-win32\ssl\certs
c:\openssl-1.0.2d-win32\ssl\private
Download this: http://curl.haxx.se/ca/cacert.pem.
Rename it to cert.pem and put it in c:\openssl-1.0.2d-win32\ssl\.
Rename it to cert.crt and put it in c:\openssl-1.0.2d-win32\ssl\certs\.
So:
c:\openssl-1.0.2d-win32\ssl\cert.pem
c:\openssl-1.0.2d-win32\ssl\certs\cert.crt
4:
Download https://getcomposer.org/Composer-Setup.exe and install it, It will no longer gives u the ERR_CONNECTION error.
Go to c:\users\YOURUSERNAME.
composer.bat should be there, if not create it yourself.
Add c:\users\YOURUSERNAME to your path.
Edit composer.bat and delete what's in it and put this in #php "%~dp0composer.phar" %*.
Download https://getcomposer.org/composer.phar.
Place composer.phar in c:\users\YOURUSERNAME.
5:
Done.
Composer will now install laravel using: composer global require "laravel/installer=~1.1" with no problem.
(Plus: now composer command is available globally instead of using it like: php composer.phar or php bin\composer).

google API with phalocon

I want to use google+ api with phalcon php framework.
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->addScope("https://www.googleapis.com/auth/urlshortener");
Before Call those Classes I want to import those classes . How can i do like this sort of things.
Best way to require those classes would be to use composer to manage them:
inside your project root create composer.json and fill with:
"require": {
"google/apiclient": "1.0.*#beta"
}
Then from the root directory run
$ composer install
Then in your bootstrap or index.php
/**
* Include composer autoloader
*/
require realpath('..') . "/vendor/autoload.php";
More information can be found at https://getcomposer.org/doc/00-intro.md

How do you run a Yii command from within your Module?

Is it possible to have my module's custom commands show up in the list of application commands when you run yiic?
cd {yii_protected_folder}
yiic shell {full_path_to_my_yii_protected_folder}/config/console.php
I've tried adding the command into the commandMap array in console.php, but the command never shows up as an option in yiic.
'commandMap'=>array(
'passwordtest'=>array(
'class'=>'application.modules.myModule.commands.shell.passwordtestCommand',
),
The only way I can make it show up in yiic is to copy the passwordtestCommand.php file to {yii_protected_folder}/commands/shell/, but I'd rather keep the file within my module and reference it somehow.
It's actually not that hard, the CConsoleApplication-class has a getter for the CConsoleCommandRunner. This in its turn has an "addCommands()"-function that allows you to add paths. Just open up your protected/yiic.php and change it by this:
<?php
defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));
defined('YII_DEBUG') or define('YII_DEBUG',true);
require_once(dirname(__FILE__).'/../yii/yii.php');
$app = Yii::createConsoleApplication(dirname(__FILE__).'/config/console.php');
$app->commandRunner->addCommands('extraCommandPath');
$app->commandRunner->addCommands('extraCommandPath2');
$app->run();
After that you no longer require the yiic.php from the framework.
That should do it.
'commandMap'=>array(
'passwordtest'=>array(
'class'=>'application.modules.myModule.commands.shell.passwordtestCommand',
),
this help me with run module command in Yii 1.x
just add it into config/console.php or your different console config file.
also change the path part ".myModule.commands.shell.passwordtestCommand"
cheer, it's working for me.