Customize prestashop web service - json

I want to customize Prestashop web service for my own usage but I don't know how and I can't find any tutorial. I have a mobile application that want to retrieve data from website but the default web service is useless.
For example I want the list of categories (in a language) with they're pictures but It seems I should call two different service to retrieve categories and images separately.
Assume I want to have a JSON array of categories that a category is a JSON object that have these fields {id,title,imageUrl} but It seems I should get {id,title} with a method and after that I can get images on by one by another method!
I couldn't find any guide for extending or customizing web service in the documentation.

I'm a bit late but:
Prestashop version requier : > 1.6
If you want to customize a web service and return specific fields with a JSON format output. You need to do it this way:
First
In override :
Create a class : myClassForWs that extends myClassCore
Override WebserviceRequest in webservice/WebserviceRequest.php
In webservice/WebserviceRequest.php : Add myClassForWs to
ressources:
public static function getResources()
{
$resources = parent::getResources();
$resources['myClassForWs'] = array('description' => 'The class','class' => 'myClassForWs');
ksort($resources);
return $resources;
}
}
In myClassForWs : redefine $webserviceParameters and $definition with the fields you need:
protected $definition = array(
'table' => 'category',
'primary' => 'id_category',
'multilang' => true,
'multilang_shop' => true,
'fields' => array(
'name' =>array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCatalogName', 'required' => true, 'size' => 128),
'link_rewrite' =>array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isLinkRewrite', 'required' => true, 'size' => 128),
'description' =>array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'),
),
);
protected $webserviceParameters = array(
'objectsNodeName' =>'categories',
'hidden_fields'=>array('nleft', 'nright', 'groupBox'),
'fields' => array(
'level_depth' => array('setter' => false),
),
'associations' => array(
'images' => array(
'resource' => 'image',
'fields' => array('id' => array())
),
),
);
Then
Go in your admin tab :
in performance : clear cache
in advanced settings > Web service: active a api Key and set myClassForWs for this key
Finally
Access to your web service with url :
my.prestashop/api/myClassForWs/{id_class}?output_format=**JSON**
And it returns your datas
I hope it helps.

Related

Multiple categories in Url

I want to create links something like that:
http://example.com/cat1/itemname-1
http://example.com/cat1/cat2/itemname-2
http://example.com/cat1/cat2/cat3/itemname-3
http://example.com/cat1/cat2/cat3/[..]/cat9/itemname-9
How rule looks like in yii2 UrlManager and how to create links for this?
Url::to([
'param1' => 'cat1',
'param2' => 'cat2',
'param3' => 'cat3',
'slug' => 'itemname',
'id' => 3
]);
Above code is really bad for multiple category params.
I add that important is only last param it means ID.
Controller looks like that:
public function actionProduct($id)
{
echo $id;
}
The below url rule would to this trick but you have to build the "slug" with the categories within your controller:
'rules' => [
['route' => 'module/controller/product', 'pattern' => '<slug:(.*)+>/<id:\d+>', 'encodeParams' => false],
]
Generate the Url:
yii\helpers\Url::toRoute(['/module/controller/product', 'slug' => 'cat1/cat2/cat3', 'id' => 1])
The output would be:
example.com/cat1/cat2/cat3/1

CakePHP basic auth on API (json) request

I want to make a request to resource/index.json, but since I index is not allowed without authentication it redirects me to login page. That's the behavior I want when no username:password has been sent
The thing is how do I set AuthComponent to work with both Form and Basic and only check for basic when the request goes through api prefix.
Also, does it automatically authenticate when found username and password in the header or do I have to do it manually?
in respective controller add few lines
class NameController extends AppController {
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow("index");
}
}
This will allow index without authentication.
I decided to use Friend's of Cake TokenAuthenticate, and yes, it works along with FormAuthenticate so I am able to use both.
As a matter of fact, it automatically chooses the component it's going to use based on if there is an existing _token param or a X-MyApiTokenHeader header.
public $components = array(
'Auth' => array(
'authenticate' => array(
'Form',
'Authenticate.Token' => array(
'parameter' => '_token',
'header' => 'X-MyApiTokenHeader',
'userModel' => 'User',
'scope' => array('User.active' => 1),
'fields' => array(
'username' => 'username',
'password' => 'password',
'token' => 'public_key',
),
'continue' => true
)
)
)
);

CakePHP HABTM Association not working

I've been trying to find an answer to my problem for hours. I am currently working with cakePHP 2.4.
I have two models, Users and Groups. I have created the following associations for each:
(User.php)
public $hasAndBelongsToMany = array(
'Group' =>
array(
'className' => 'Group',
'joinTable' => 'groups_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'group_id',
'unique' => true,
)
);
and (Group.php):
public $hasAndBelongsToMany = array(
'GroupUser' =>
array(
'className' => 'User',
'joinTable' => 'groups_users',
'foreignKey' => 'group_id',
'associationForeignKey' => 'user_id',
'unique' => true,
)
);
The reason I use GroupUser and not "User" is I get an error because I have already used "User for some other relation.
My form looks like this:
echo $this->Form->create('Group', array('controller' => 'group','action' => 'add'));
echo $this->Form->input('User.id', array('type' => 'hidden', 'value' => $authUser['id']);
echo $this->Form->input('Group.address');
echo $this->Form->end(__('Save', true));
I also have a table called groups_users with "id", "user_id" and "group_id"
When I submit the form, it created the new Group and saves the data, but the association is not created.
I tried manually filling a groups_users record with an existing user_id and group_id but still, when I use find(All), it doesn't find the expected association like it should according to the books.
I debugged the array that is being saved and it looks like this:
Array
(
[User] => Array
(
[user_id] => 39
)
[Group] => Array
(
[address] => asdasd, San Antonio, Texas 78233, EE. UU.
)
)
This is the code in my GroupsController add function:
if ($this->Group->save($this->request->data)) {
// redirect or do something
}
I have tried changing the array to work with saveAll like in the books, still only created new record but no association. And as I said, I mannually created a record and tried finding it and it wouldn't find it anyway.
I solved it apparently, I think it was because I hadn't created the GroupsUser.php model file. Not rreally sure because I changed a bunch of stuff! But maybe it helps someone.

Convert a named route to a hash (#) in CakePHP

In CakePHP, I want to convert this URL
example.com/FAQ/What-came-first-the-chicken-or-the-egg
to
example.com/FAQ#What-came-first-the-chicken-or-the-egg
using the routes.php and have the browser scroll to that anchor.
I tried this:
Router::connect('/FAQ/:faq',
array('controller' => 'pages', 'action' => 'faq', '#' => ':faq'),
array('faq' => '[A-Za-z-_]+')
);
If I then do debug($this->request->params), is says
array(
'plugin' => null,
'controller' => 'pages',
'action' => 'FAQ',
'named' => array(),
'pass' => array(),
'faq' => 'What-came-first-the-chicken-or-the-egg',
'#' => ':faq'
)
and the browser doesn't scroll anywhere.
Not possible
A webserver has no visibility whatsoever of the url fragment, as such routes based on the url fragment will never work.
Your route needs to match the received url
If you request the url /Foo/#hash in a browser, the server will only receive /Foo/ - this is the url that cake sees, this is the url that must match a route if you don't want to see errors. As such your route needs to be:
Router::connect('/FAQ',
array('controller' => 'pages', 'action' => 'faq')
);
Incidentally that's an odd route - the pages controller comes with a dynamic display function, it's not normal to create actions in this controller, rather use it like so:
Router::connect('/FAQ',
array('controller' => 'pages', 'action' => 'display', 'faq')
);
I have not tested it:
Router::connect('/FAQ/#:faq',
array('controller' => 'pages', 'action' => 'faq'),
array(
'pass' => array('faq'),
'faq' => '[A-Za-z-_]+'
)
);

Magento Admin Create and Save HTML to Database With a Form Field

I am working on a module that requires some html to be entered to be later called upon and become part of a customer facing widget output.
I've created an administrative backend and that is all working properly, however when I enter html into the field that should be storing the data i receive an error.
I dont need the wysiwyg but I would like to be able to enter html into this value.
At this point I've not done anything special when adding the field to the fieldset. What am I missing?
$contentField = $fieldset->addField('inner_html', 'editor', array(
'name' => 'inner_html',
'style' => 'height:36em;width:36em',
'required' => false,
));
Try
$fieldset->addField('inner_html', 'editor', array(
'name' => 'inner_html',
'label' => Mage::helper('tag')->__('Description'),
'title' => Mage::helper('tag')->__('Description'),
'style' => 'width:700px; height:350px;',
'config' => Mage::getSingleton('cms/wysiwyg_config')->getConfig(array('add_variables' => false, 'add_widgets' => false,'files_browser_window_url'=>$this->getBaseUrl().'admin/cms_wysiwyg_images/index/')),
'wysiwyg' => true,
'required' => false,
));