I'm pretty new to PrestaShop - so sry if i ask basic thing
I'm currently working on a module which should display products you chose in the backend as additional section in the default products template - like "highly recommended products"
I finish the whole Backend part, and get the ID's as an array of the chosen products.
As I mentioned I wanna use the default templates which are available after a fresh installation and what I found is placed here themes\classic\templates\catalog\_partials\products.tpl.
Now my big problem is: I'm not able to get the data like it should be ...
If I debug e.g. the products which are displayed in the default search behaviour (this uses this template too) I see something like
object(PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductListingLazyArray)#323 (11) { ["imageRetriever":"Pr .....
but as I get my products with
new Product($productId, true);
it is no ProductListingLazyArray ... its just an array with products ... and i dont see anything in the frontend (of course I dont, cause e.g. {$product.id_product} doesnt look like this in my array ...
Have you any ideas what I can do to "transform" my array of products to an ProductListingLazyArray ??
Or is my thinking wrong ?
THANKS to you all!
Solution
I just "faked" a search and check if the data is in my array:
/**
* creates relevant product information for frontend output
*
* #param array $allSelectedProductIds array with all id's of the selected products
* #param int $languageId language id of the shop you are in
*
* #return array all product information we need for our frontend rendering
*/
public function getFrontendProductInformation($allSelectedProductIds, $languageId)
{
// set default category Home
$category = new Category((int)2);
// create new product search proider
$searchProvider = new CategoryProductSearchProvider(
$this->context->getTranslator(),
$category
);
// set actual context
$context = new ProductSearchContext($this->context);
// create new search query
$query = new ProductSearchQuery();
$query->setResultsPerPage(PHP_INT_MAX)->setPage(1);
$query->setSortOrder(new SortOrder('product', 'position', 'asc'));
$result = $searchProvider->runQuery(
$context,
$query
);
// Product handling - to get relevant data
$assembler = new ProductAssembler($this->context);
$presenterFactory = new ProductPresenterFactory($this->context);
$presentationSettings = $presenterFactory->getPresentationSettings();
$presenter = new ProductListingPresenter(
new ImageRetriever(
$this->context->link
),
$this->context->link,
new PriceFormatter(),
new ProductColorsRetriever(),
$this->context->getTranslator()
);
$products = array();
foreach ($result->getProducts() as $rawProduct) {
$productId = $rawProduct['id_product'];
if(in_array($productId, $allSelectedProductIds)) {
$product = $presenter->present(
$presentationSettings,
$assembler->assembleProduct($rawProduct),
$this->context->language
);
array_push($products, $product);
}
}
return $products;
}
I have a model with title, subtitle, date and am building a form that will allow a user to submit a change request.
How can I validate to ensure at least one edit is made comparing the input fields to database values?
I think the below would ensure the title entered is different from the value in 'different:', but how would I only do this for at least one field?
public function rules()
{
return [
'title' => [
'required',
'different:Dynamic Title name here',
'string',
'max:60',
'not_regex:/[\x{1F600}-\x{1F64F}]/u'
],
'subtitle' => [
'string',
'nullable',
'max:90',
'not_regex:/[\x{1F600}-\x{1F64F}]/u'
]
];
}
e.g.
Title, Subtitle, Date fields are shown. A user must edit at least one of them from the current set database values in order to submit.
I don't know your solution, but I'd recommend to take a look at isDirty() function.
/**
* this will return false, because after we get the record from
* database, there's no attribute of it that we changed. we just
* print if it's dirty or not. so it tells us: "I'm clean, nobody has
* changed my attributes at all.
*/
$role = Role::findOrFail(1);
return $role->isDirty();
/**
* lets say We fetched this role with id=1 and its status was 1. what
* this returns is still false, because even though we set the status
* attribute equal to 1, we still didn't change it. It was 1 when we
* received it from the database and it's still 1.
*/
$role = Role::findOrFail(1);
$role->status = 1;
return $role->isDirty();
/**
* now if the status was 1 in the db, and we set it to 2, it will
* print the true.
*/
$role = Role::findOrFail(1);
$role->status = 2;
return $role->isDirty();
You can also pass an argument to isDirty() function which will only check that specific column value.
I have added a new field to my table Empresa so I need to change my model. For not regenerate the whole things meaning model-forms-filters I decide to add it by hand (manually) so I'm trying to add a the property to BaseSdrivingEmpresa.class.php as follow:
<?php
/**
* BaseSdrivingEmpresa
*
* This class has been auto-generated by the Doctrine ORM Framework
*
* #property integer $umbralvoz
*
* #method integer getUmbralvoz() Returns the current record's "umbralvoz" value
* #method SdrivingEmpresa setUmbralvoz() Sets the current record's "umbralvoz" value
*
* #package isecurdriving
* #subpackage model
* #author Your name here
* #version SVN: $Id: Builder.php 7490 2010-03-29 19:53:27Z jwage $
*/
abstract class BaseSdrivingEmpresa extends sfDoctrineRecord {
public function setTableDefinition() {
$this->setTableName('sdriving_empresa');
$this->hasColumn('umbralvoz', 'integer', 11, array(
'type' => 'integer',
'notnull' => false,
'default' => 60,
'length' => 11,
));
}
}
But I get this error:
500 | Internal Server Error | Doctrine_Record_UnknownPropertyException
Any time I try to get the property to display it on a template:
$id_empresa = $this->getUser()->getGuardUser()->getSfGuardUserProfile()->getIdempresa();
$this->sdriving_configuracion = Doctrine_Core::getTable('SdrivingEmpresa')->createQuery('a')->where('a.idempresa = ?', $id_empresa)->execute();
<?php echo $sdriving_configuracion[0]->SdrivingEmpresa->getUmbralvoz() ?>
Where is my error?
First of all manual edit of your Base*.class.php is not a good idea as this class is meant to be generated automatically and will be overwritten by next model build. If you want to do anything manually you should do it in direct child of BaseSdrivingEmpresa.class.php which is SdrivingEmpresa.class.php.
Second thing is that better place for such modification is SdrivingEmpresaTable.class.php. I would suggest modifying getInstance method so it looks like:
public static function getInstance()
{
$this->setColumn('umbralvoz', 'integer', 11, array(
'type' => 'integer',
'notnull' => false,
'default' => 60,
'length' => 11,
));
return Doctrine_Core::getTable('SdrivingEmpresa');
}
Finally, I think that in this case best solution is just simply modify your schema.yml file, add your column and then use command
./symfony doctrine:build-model
which will rebuild your model without touching forms, filters which you mentioned.
I'm trying to save HTML text to database safely in Joomla 2.5, so I'm using JInput to get the form data.
According to developer.joomla.org, there is HTML filter:
HTML - Returns a string with HTML entities and tags intact, subject to
the white or black lists in the filter.
According to docs.joomla.org, there are these filter which should (logically. They are not explained there) pass HTML tags:
RAW, HTML, SAFE_HTML
At the code JFilterInput::clean which JInput uses for filtering, there is no SAFE_HTML filter. I don't know what it is doing in one documentation and why RAW filter is missing in another. Apart from that, all these filters strip HTML tags anyway.
With just $_POST:
$_POST['shortDescription'];
returns
<b>Hello <i>world</i></b>
When I use JInput:
$input->get('shortDescription', '', 'RAW');
$input->get('shortDescription', '', 'HTML');
$input->get('shortDescription', '', 'SAFE_HTML');
all returns just
Hello world
without HTML tags. What is it for then? How to use it when I need to store HTML safely?
I bypased it with this method:
public function getHtmlInput($htmlText)
{
$input_options = JFilterInput::getInstance(
array(
'img','p','a','u','i','b','strong','span','div','ul','li','ol','h1','h2','h3','h4','h5',
'table','tr','td','th','tbody','theader','tfooter','br'
),
array(
'src','width','height','alt','style','href','rel','target','align','valign','border','cellpading',
'cellspacing','title','id','class'
)
);
$postData = new JInput($_POST, array('filter' => $input_options));
return $postData->get($htmlText, '', 'HTML');
}
Usage:
$this->getHtmlInput('documentation');
I hope this is solved in Joomla 3...
You should do this:
$jinput = JFactory::getApplication()->input;
$html = JComponentHelper::filterText($jinput->post->get('shortDescription', '', 'raw'));
This is an old post but I figured I would throw my 2 cents in as it might help people finding this post searching for a solution.
Using an html editor it still strips the html with using the HTML filter. To get around it I use ARRAY as the filter instead and then just implode the result.
Easy bo breazy.
(In the context of Joomla 3.x) The default configuration of a JInputFilter instance is to operate in whitelisting mode, with empty arrays of whitelisted tags and attributes ie. the most restrictive possible mode of HTML filtering that effectively gets rid of everything.
This clearly isn't that useful out of the box, but it is opting for security over convenience, and leaving it up to developers to make a conscious decision to relax the security to accept tags and attributes in the received content by using an alternate JInputFilter instance, either:
A) with a specified whitelist of tags (what #Jon ultimately did in his own answer)
$filter = JInputFilter::getInstance(array('img', ...), array('src', ...));
or
B) configured to operate in blacklist mode
$filter = JInputFilter::getInstance([], [], 1, 1);
As an aside, unless you disable the $xssAuto option (see usage below), Joomla will enforce the following blacklists irrespective of which mode the JInputFilter instance is configured with:
Tags: 'applet', 'body', 'bgsound', 'base', 'basefont', 'embed', 'frame', 'frameset', 'head', 'html', 'id', 'iframe', 'ilayer', 'layer', 'link', 'meta', 'name', 'object', 'script', 'style', 'title', 'xml'
Attributes: 'action', 'background', 'codebase', 'dynsrc', 'lowsrc'
For reference, here is the usage information for the JFilterInput::getInstance method:
/**
* Returns an input filter object, only creating it if it doesn't already exist.
*
* #param array $tagsArray List of user-defined tags
* #param array $attrArray List of user-defined attributes
* #param integer $tagsMethod WhiteList method = 0, BlackList method = 1
* #param integer $attrMethod WhiteList method = 0, BlackList method = 1
* #param integer $xssAuto Only auto clean essentials = 0, Allow clean blacklisted tags/attr = 1
* #param integer $stripUSC Strip 4-byte unicode characters = 1, no strip = 0, ask the database driver = -1
*
* #return JFilterInput The JFilterInput object.
*
* #since 11.1
*/
public static function &getInstance($tagsArray = array(), $attrArray = array(), $tagsMethod = 0, $attrMethod = 0, $xssAuto = 1, $stripUSC = -1)
Joomla also provides configurable filtering rules on the Text Filters tab of the Global Configuration page in the administration interface. Here, you can configure the mode of operation, as well as the tags and attributes to be filtered on a per user group basis. To take advantage of this in your own code, use the JComponentHelper::filterText() method, per #xavip's answer.
Consider a view called render_thing, which I load from a controller like so:
$html = $this->load->view(
'render_thing',
array(
'someParam' => $globalParam
'permissionMode' => 'guest'
),
true
);
log($html);
Later on in that same controller, I load the view again, except I don't override the optional permissionMode parameter. I'm assume that in the view code, $permissionMode would be unset.
$moreHtml = $this->load->view(
'render_thing',
array(
'someParam' => 'blablabla'
),
true
);
However, in the render_thing view code, on the second call, $permissionMode is still 'guest'. Can you tell me what is going on here?
Thanks!!!
From Loader.php, Loader::_ci_load in the CodeIgniter source...
/*
* Extract and cache variables
*
* You can either set variables using the dedicated $this->load_vars()
* function or via the second parameter of this function. We'll merge
* the two types and cache them so that views that are embedded within
* other views can have access to these variables.
*/
if (is_array($_ci_vars))
{
$this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
}
extract($this->_ci_cached_vars);
So, this would be why the parameter is still set. load_vars is not a method, but vars is; problem is that it doesn't provide a facility to erase the cache. Therefore, since CodeIgniter is still PHP4 compatible, you may always do this: $this->load->_ci_cached_vars = array();.
I've had the same problem and figured out the problem in Loader.php as follows;
/*
* Extract and cache variables
*
* You can either set variables using the dedicated $this->load_vars()
* function or via the second parameter of this function. We'll merge
* the two types and cache them so that views that are embedded within
* other views can have access to these variables.
*/
if (is_array($_ci_vars))
{
$this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
}else{
$this->load->_ci_cached_vars = array();
}
extract($this->_ci_cached_vars);