Yii UrlManager partial render of URL - yii

I need to make url with some of parametres been as query string, like:
site.com/controller/action/param1/param2?param3=value&param4=value
Can someone help me with this problem?

You should set this rule in config:
'rules'=>array(
array('controller/action', 'pattern'=>'controller/action/<param1:\w+>/<param2:\w+>'),
)
and to create same url:
Yii::app()->createAbsoluteUrl(
'controller/action',
array('param1'=>'param1value', 'param2'=>'param2value', 'param3'=>'param3value', 'param4'=>'param4value'
);
and you get this url:
http://example.com/controller/action/param1value/param2value?param3=param3value&param4=param4value
and get parameters will be
$_GET['param1'] //'param1value'
$_GET['param2'] //'param2value'
$_GET['param3'] //'param3value'
$_GET['param4'] //'param4value'

I found the solution.
I created component extended from CBaseUrlRule.
class CCustomUrlRule extends CBaseUrlRule {
private $url;
public function init()
{
if ($this->name === null) {
$this->name = __CLASS__;
}
}
public function createUrl($manager,$route,$params,$ampersand)
{
if ($route === 'controller/index') {
$this->url = 'controller/';
if (isset($params['param1'])) {
$this->url .= 'param1/' . $params['param1'] .'/';
}
if (isset($params['param2'])) {
$this->url .= 'param2/' . $params['param2'] .'/';
}
$this->url = substr($this->url, 0, -1);
if (isset($params['param3']) || isset($params['param4'])) {
$this->url .= '?';
if (isset($params['param3']) && isset($params['param4'])) {
$this->url .= 'param3=' . $params['param3'] .'&';
$this->url .= 'param4=' . $params['param4'];
}
elseif (isset($params['param3'])) {
$this->url .= 'param3=' . $params['param3'];
}
else {
$this->url .= 'param4=' . $params['param4'];
}
}
return $this->url;
}
return false;
}
public function parseUrl($manager,$request,$pathInfo,$rawPathInfo)
{
return false;
}
}
I know - it is to match code but it is work and easy to customize.

Related

Validator not validating the request in Laravel 8

I am inserting the data. The data is being entering quite fine but whenever I enter a letter the entry is done but that entry is converted to '0'.
This is my controller store function:
public function store(GuidanceReportRequest $request)
{
$stats = GuidanceReport::where('user_id', $request->user_id)->whereDate('created_at', now())->count();
if ($stats > 0) {
Session::flash('warning', 'Record already exists for current date');
return redirect()->route('reports.index');
}
if ((!empty($request->call_per_day[0]) && !empty($request->transfer_per_day[0])) ||
(!empty($request->call_per_day[1]) && !empty($request->transfer_per_day[1])) || (!empty($request->call_per_day[2])
&& !empty($request->transfer_per_day[2]))
) {
foreach ($request->category as $key => $value) {
$catgeory_id = $request->category[$key];
$call_per_day = $request->call_per_day[$key];
$transfer_per_day = $request->transfer_per_day[$key];
if (!empty($catgeory_id) && !empty($call_per_day) && !empty($transfer_per_day)) {
GuidanceReport::create([
"user_id" => $request->user_id,
"categories_id" => $catgeory_id,
"call_per_day" => $call_per_day,
"transfer_per_day" => $transfer_per_day,
]);
}
}
} else {
GuidanceReport::create($request->except('category', 'call_per_day', 'transfer_per_day'));
}
Session::flash('success', 'Data Added successfully!');
return redirect()->route('reports.index');
}
This is my Validation Request code
public function rules()
{
$rules = [];
$request = $this->request;
if ($request->has('transfer_per_day')) {
if (!empty($request->transfer_per_day)) {
$rules['transfer_per_day'] = "numeric";
}
}
if ($request->has('call_per_day')) {
if (!empty($request->call_per_day)) {
$rules['call_per_day'] = "numeric";
}
}
if ($request->has('rea_sign_up')) {
if (!empty($request->rea_sign_up)) {
$rules['rea_sign_up'] = "numeric";
}
}
if ($request->has('tbd_assigned')) {
if (!empty($request->tbd_assigned)) {
$rules['tbd_assigned'] = "numeric";
}
}
if ($request->has('no_of_matches')) {
if (!empty($request->no_of_matches)) {
$rules['no_of_matches'] = "numeric";
}
}
if ($request->has('leads')) {
if (!empty($request->leads)) {
$rules['leads'] = "numeric";
}
}
if ($request->has('conversations')) {
if (!empty($request->conversations)) {
$rules['conversations'] = "numeric";
}
}
return $rules;
}
Although I check the type in which request is being sent from controller and recieved from the request validation and it is Object. So how can I solve the issue.

update the uploaded file yii2

I have used following to upload image and save it in server and database. Now I want to write a controller to update the uploaded image. how to do it???
controller
public function actionInvitfile()
{
$model = new Applicants();
$imgName = Yii::$app->user->identity->id;
if($model->load(Yii::$app->request->post())){
$model->file = UploadedFile::getInstance($model, 'file');
$model->file->saveAs('uploads/invitfile/' . $imgName . '.' . $model->file->extension);
$model->invitations_file='uploads/invitfile/'. $imgName . '.' . $model->file->extension;
$model->save(false);
}
return $this->goHome();
}
Model
class Applicants extends \yii\db\ActiveRecord
{
public $file;
public static function tableName()
{
return 'applicants';
}
public function rules()
{
return [
[['file'], 'file', 'skipOnEmpty' => true, 'extensions' => 'pdf'],
];
}
Please, Help me!)
I think this can work
public function actionUpdate($id)
{
$imgName = Yii::$app->user->identity->id;
$model = Applicants->findModel($id);
if($model->load(Yii::$app->request->post())){
unlink($model->invitations_file);
$model->file = UploadedFile::getInstance($model, 'file');
$model->file->saveAs('uploads/invitfile/' . $imgName . '.' . $model->file->extension);
$model->invitations_file='uploads/invitfile/'. $imgName . '.' . $model->file->extension;
$model->save(false);
}
return $this->goHome();
}
but here you have official documentation of the kartij blog where you can learn much more and have a better answer to your problem:
http://webtips.krajee.com/advanced-upload-using-yii2-fileinput-widget/
If you want to update a single image, then in update function, before loading post variables, just keep the old image in a variable. The following code will help you:
public function actionUpdate($id)
{
$model = $this->findModel($id);
$oldImage = $model->banner;
if ($model->load(Yii::$app->request->post())) {
//get picture data and save it
$imageFile = \yii\web\UploadedFile::getInstance($model, 'banner');
if($imageFile) {
unlink(Yii::getAlias('#app').'/../../uploads/banners/' . $oldImage);
$fileName = $imageFile->baseName.'_'.time().'.'.$imageFile->extension;
$imageFile->saveAs(Yii::getAlias('#app').'/../../uploads/banners/' . $fileName);
$model->banner = $fileName;
$model->save();
} else {
$model->banner = $oldImage;
$model->save(false);
}
return $this->redirect(['index']);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}

How to send ecommerce data to datalayer in prestashop

I am not a developer but trying to send ecommerce data to datalayer. I can't see any ecommerce data to datalayer in console. I am adding the data to order-confirmation.tpl in prestashop. below is how i am sending data
<Script type = "text / javascript">
dataLayer = ( {
'transactionId' : '{literal} {$order_id} {/literal}' ,
'transactionTotal' : {literal } { $total_a_payment } {/literal } ,
'transactionTax' : { literal } { $tax } { /literal } ,
'transactionShipping' : { literal } { $ expenses_envoice } { /literal
} ,
'transactionProducts' : [ { /literal } { foreach from = $ products
item = product name = products } { /literal }
{
'Sku' : '{literal}{$producto.id_product}{/literal}' ,
'Name' : '{literal}{$producto.name}{/literal}' ,
'Price' : { literal } { $ product . Price_wt } { /literal } ,
'Quantity' : { literal } { $ product . Quantity } { /literal }
} { Literal} {if $ smarty.foreach.productos.iteration! = $ Products
| #count} {literal}, {/ literal } { / if } { /literal }
{ Literal} {/ foreach } ] , { /literal }
'Event' : 'transactionComplete'
} )
</ Script>
{ / Literal }
anyone have experience with prestashop please help. I am using Google Tag Manager for ecommerce tracking. thanks
I had the same issue. You have to also edit file controllers/front/OrderConfirmationController.php.
Find function displayOrderConfirmation and insert something like this part of code:
$order = new Order($this->id_order);
$currency = new Currency($order->id_currency);
/* added part */
$cart = new Cart($order->id_cart);
$products = $cart->getProducts();
$this->context->smarty->assign(array(
'order_id'=> $this->id_order,
'total_a_payment'=> $order->total_paid_tax_incl,
'expenses_envoice'=> $order->total_shipping_tax_incl,
'tax'=> ($order->total_paid_tax_incl - $order->total_paid_tax_excl),
'products' => $products
));
/*end of added*/
Original source: https://www.prestashop.com/forums/topic/618328-variables-for-google-tag-manager/

Codeception: acceptance test with selenium fails on "textarea"

I've got a function:
public function waitAndFill($element, $value, $timeOut = null)
{
$I = $this;
$I->_waitFor($element, $timeOut);
$I->fillField($element, $value);
$I->seeInField($element, $value);
}
And I use it like this:
$I->waitAndFill('#inputInfo', 'This is test info');
The textarea looks as follows
<textarea id="inputInfo"
name="company_description"
ng-model="company.company_description"
class="form-control"></textarea>
So, my test fails with this:
Step I see in field "#inputInfo","This is test info"
Fail Failed testing for 'This is test info' in company_description's value:
Failed asserting that an array contains 'This is test info'.
It works fine on <input> fields, but fails on <textarea>. Looks like it doesn't see any text at all.
This text is present on the screen shot made by the test.
What am I doing wrong?
It's a bug. The problem is this: $I->seeInField($element, $value); invokes $this->proceedSeeInField(array $elements, $value); which invokes a method getText() on the Facebook\WebDriver\Remote\RemoteWebElement object that it finds. If you read the documentation for Facebook\WebDriver\Remote\RemoteWebElement#getText() method it says that it returns the innerText for that element. So that's no bueno. To workaround this I removed the conditional for the textarea in this function.
protected function proceedSeeInField(array $elements, $value)
{
$strField = reset($elements)->getAttribute('name');
if (reset($elements)->getTagName() === 'select') {
$el = reset($elements);
$elements = $el->findElements(WebDriverBy::xpath('.//option[#selected]'));
if (empty($value) && empty($elements)) {
return ['True', true];
}
}
$currentValues = [];
if (is_bool($value)) {
$currentValues = [false];
}
foreach ($elements as $el) {
if ($el->getTagName() === 'textarea') {
$currentValues[] = $el->getText();
} elseif ($el->getTagName() === 'input' && $el->getAttribute('type') === 'radio' || $el->getAttribute('type') === 'checkbox') {
if ($el->getAttribute('checked')) {
if (is_bool($value)) {
$currentValues = [true];
break;
} else {
$currentValues[] = $el->getAttribute('value');
}
}
} else {
$currentValues[] = $el->getAttribute('value');
}
}
return [
'Contains',
$value,
$currentValues,
"Failed testing for '$value' in $strField's value: " . implode(', ', $currentValues)
];
}
You should change it to:
protected function proceedSeeInField(array $elements, $value)
{
$strField = reset($elements)->getAttribute('name');
if (reset($elements)->getTagName() === 'select') {
$el = reset($elements);
$elements = $el->findElements(WebDriverBy::xpath('.//option[#selected]'));
if (empty($value) && empty($elements)) {
return ['True', true];
}
}
$currentValues = [];
if (is_bool($value)) {
$currentValues = [false];
}
foreach ($elements as $el) {
if ($el->getTagName() === 'input' && $el->getAttribute('type') === 'radio' || $el->getAttribute('type') === 'checkbox') {
if ($el->getAttribute('checked')) {
if (is_bool($value)) {
$currentValues = [true];
break;
} else {
$currentValues[] = $el->getAttribute('value');
}
}
} else {
$currentValues[] = $el->getAttribute('value');
}
}
return [
'Contains',
$value,
$currentValues,
"Failed testing for '$value' in $strField's value: " . implode(', ', $currentValues)
];
}
Now it calls getAttribute('value') just like any other input element.
The is in file WebDriver.php

Laravel4: WhereHas Eloquent Issue (nested). callback function error

I tried doing a search function where the only field would be an <input type='text' /> it'll be stripped into an array() then passed to a whereLoop.
static function generateSearch($fields, $queryString)
{
return function($query) use($queryString, $fields)
{
foreach($fields as $field) {
$query = $query->orWhere($field, 'like', $queryString);
}
$query = $query->whereHas('category', function($_query) use ($queryString)
{
$_query->where('name','like',$queryString);
});
};
}
public static function search($query)
{
$searchBits = explode(' ', $query);
$query = Lead::with(array('user', 'category'));
$ctr = 0;
if(Category::whereIn('name', $searchBits)->count() != 0) {
$query = $query->whereHas('category', function($query) use ($searchBits)
{
$ctr = 0;
foreach($searchBits as $bit) {
$bit = "%".$bit."%";
$callback = "orWhere";
$queryFunc = Lead::generateSearch(array('name'), $bit);
if($ctr == 0) {
$callback = "where";
}
$query = $query->$callback($queryFunc);
}
});
}else {
foreach($searchBits as $bit) {
$bit = "%".$bit."%";
$callback = "orWhere";
$queryFunction = Lead::generateSearch(array('name', 'website', 'name', 'email'), $bit);
if($ctr == 0) {
$callback = "where";
}
$query = $query->$callback($queryFunction);
$ctr++;
}
}
$query = $query->orderBy('id','desc');
return $query;
}
Category only has ONE row as of the moment: its - "hot"
if i type in any keyword, it'll directly go to generateSearch()
but if i type in "hot", it'll send an error
Call to undefined method
Illuminate\Database\Query\Builder::category()
does anybody know what's up?
found the error. after looking deep within the callstack. i should not have added the
$query = $query->whereHas('category', function($_query) use ($queryString)
{
$_query->where('name','like',$queryString);
});
inside the generateSearch() or i should create another function for it. its being called by category callback as well.