How to use article name on the url on Yii2? - yii2

I need to use article name on the url on Yii2 which is like http://example.com/article?id=1, just replace id=1 to article_name, like http://example.com/article/article_name or is it.
This is my controller code-
$model = Articles::find()->orderBy(['id' => SORT_DESC])->one();
View-
<?= Html::a('<b>Read more ...</b>', ['article-details','id' => $model->id], ['target'=>'_blank']) ?>
Thanks advance

You may use yii2 sluggable behavior Refer this.
There are few steps.
You must add the following urlManager rule :
'article/<slug>' => 'article/view',
You should build url in your view files like this :
\yii\helpers\Url::to(['article/view', 'slug'=>$model->title])
or
\yii\helpers\Url::to(['article/'.$model->title]);
And in your action
public function actionArticle($slug){
$model = Articles::find()->where(["title"=>$slug])->orderBy(['id' => SORT_DESC])->one();
//and other code
}
Also your article titles must be valid for url.You can do it easly by trimming whitespaces and so on But also you can add url some identification propery. or add column stored unique slugs for every article

You have two way
one change the related action in the controller changing id with name in the related function declaration
or declare a new action with the name as parameter
public function findModelName($article_name)
{
$model = Article::findOne(['name'=> $article_name]);
........ your related code
}
you can find the model by name this way
Article::findOne(['name'=> $article_name]);

Related

Yii2 - Checkboxlist Value Store In Database

in my db structure
service_request type enum('towel','tissue','napkin')
then have a model
* #property string $service_request
then in my view
<?= $form->field($model, 'service_request')->checkBoxList([ 'towel' => 'Towel', 'tissue' => 'Tissue', 'napkin' => 'Napkin']) ?>
then when i choose towel, tissue and napkin then submit the form, it's have an error said
Service Request must be String
please help me
Thank You
Like Joji Thomas said, checkBoxList prodices an array.
You need to change your database structure so that it supports 1-to-many relations (each $model can have multiple service_requests) if you want to save this. Unfortunately Yii is not very good at this sort of thing out of the box so you have to do a bunch of things yourself.
First you need to create a ServiceRequest ActiveRecord.
Then your $model needs to have a relation like:
public function getServiceRequests() {
return $this->hasMany(ServiceRequest::className(), ['model_id' => 'id'];
}
Then in your controller (model create action) you will need to do something like this:
foreach (Yii::$app->request->post('ServiceRequest',[]) as $data) {
$item = new ServiceRequest($data);
$model->link('serviceRequests', $item);
}
If you wanna update the checkboxes too then you need to do something similar in your model update action as well.
Please change checkBoxList to radioList, because when selecting multiple values service_request becomes an array. Enum type can handle only string values.
First change your filed datatype from enum to varchar. enum only takes a single string value.
Secondly you need to implode service_request array to string for save to db.
Use bellow code before the model save function :
$model->service_request = implode("," , $model->service_request);
$model->save();

How to use the search() function in yii2 to search for more than 1 condition?

In my controller in yii2 I have the following:
$searchModel = new HealthSearch();
$dataProvider = $searchModel->search(['HealthSearch'=>['zip'=>$zipcode]]);
which works but I would like it to also search for zipcodes and speciality
I tried:
$dataProvider = $searchModel->search(['HealthSearch'=>['zip'=>$zipcode,'pri_spec'=>$sspec']]);
but that does not work? What is the correct way of searching??
After removing the last single quoted '. Your code should work fine. An easier to read version may look like :
$searchByAttr['HealthSearch'] = [
'zip' => $zipcode,
'pri_spec' => $sspec
];
$dataProvider = $searchModel->search($searchByAttr);
Also you need to check the HealthSearch class which is the first responsible of making that search. Gii generates a primary boilerplate from your model that need to be adapted to your app in further steps. By default the HealthSearch::search() method should filter by all model's safe attributes and as any ActiveRecord class it has also a rules() method that returns those safe attributes. So if zip and pri_spec are not included in that array they will be simply ignored.

Use URL slug in cakephp 3.x

I can create without problem a record slug with the title in cakephp 3.x. Now I want to use that field slug on the URL.
How can I do that?
I try with the typical function view changing $id by $slug...
public function view($slug = null)
{
$noticia = $this->Noticias->get($slug, [
'contain' => ['Categorias', 'Usuarios', 'Etiquetas', 'Fotos']
]);
$this->set('noticia', $noticia);
$this->set('_serialize', ['noticia']);
}
but I have the following error: "Record not found in table "noticias".
Thank you
The get() method can only be used to find record by primary key. Instead, you need to use find():
$noticia = $this->Noticias
->findBySlug($slug)
->contain(['Categorias', 'Usuarios', 'Etiquetas', 'Fotos'])
->firstOrFail();

Generate link in cakephp using Html helper

I am trying to simply create a link in my controller using the Html helper and I get the below error although I have added the necessary helper:
Call to a member function link() on a non-object
public $helpers = array('Html', 'Form');
$url = $this->Html->link(
'',
'http://www.example.com/',
['class' => 'button', 'target' => '_blank']
);
You can use Helpers inside your view files but not inside your controller
http://book.cakephp.org/2.0/en/views/helpers.html#using-helpers.
For example in your index.ctp
echo $this->Html->link(
__('My link'),
'http://www.example.com/',
array('class' => 'button', 'target' => '_blank')
);
Enabling Html Helper in your Controller is same as in your code.
class ExamplesController extends AppController {
$helpers = array('Html', 'Form');
public function index() {
//
}
}
This is a good question. I think your a little confused with MVC and the separation of concerns the design pattern provides. Take a look (again) at how CakePHP implements MVC: http://book.cakephp.org/2.0/en/cakephp-overview/understanding-model-view-controller.html.
The important thing to remember is that your controllers should never be concerned with creating anchor tags. That's the job of your views. Since helpers are a way to keep your views DRY (Don't Repeat Yourself) having one thats sole responsibility is to create HTML elements is really handy. Views are dependent on controllers to determine what variables are set, what their value is, as well as what helpers are loaded. For more information on Helpers as well as components for controllers and behaviors for models check out http://book.cakephp.org/2.0/en/getting-started/cakephp-structure.html as well as each of their individual documentation pages:
Helpers - http://book.cakephp.org/2.0/en/views/helpers.html
Components - http://book.cakephp.org/2.0/en/controllers/components.html,
Behaviors - http://book.cakephp.org/2.0/en/models/behaviors.html.
Now that you have a better understanding of MVC, let's take a look at your specific issue. Your wanting to create a link in your controller. I assume it might be dynamic depending on some other variables so I'm going to roll with that.
A common problem that you can solve you want to show a login/logout link depending on if the user is already logged in.
In app/Controller/ExampleController.php
class ExampleController extends AppController {
public $components = array('Auth');
public $helpers = array('Html', 'Form');
public function beforeRender() {
parent::beforeRender();
//if Auth::user() returns `null` the user is not logged in.
if ($this->Auth->user() != null) {
$logInOutText = 'Log out';
$logInOutUrl = array('controller' => 'users', 'action' => 'login');
} else {
$logInOutText = 'Log in';
$logInOutUrl = array('controller' => 'users', 'action' => 'logout');
}
$this->set(compact('logInOutText', 'logInOutUrl'));
}
}
You can then so something simple in your view. In this case I'm choosing the default layout because I want the links in every rendered page. app/View/Layouts/default.ctp
<!-- More HTML above -->
<?php
// "Html" in `$this->Html` refers to our HtmlHelper. Note that in a view file
// like a `.ctp`, `$this` referes to the View object, while above in the
// controller `$this` refers to the Controller object. In the case
// `$this->Html`, "Html" would refer to a component. The same goes for Models
// and behaviors.
echo $this->Html->link($logInOutText, $logInOutUrl); // Easy!
?>
<!-- More HTML below -->
I hope this helps. I know it's a lot to put together at one time.
Though it is not good practice. However still if you need this you can use following code in your controller
App::uses('HtmlHelper', 'View/Helper');
$yourTmpHtmlHelper = new HtmlHelper(new View());
$url=$yourTmpHtmlHelper->link(
'',
'http://www.example.com/',
['class' => 'button', 'target' => '_blank']
);
This should work for cakephp 2.*
Thanks

YII2 : Use activeForm and linkPager toghether

I would like to use an activeForm and linkPager together.
I mean in the same view, I have defined an activeform with some fields, an sqldataprovider and the showing of the model result (of sqldataprovider). All is nice when I click on the submit button of the activeform.
Now, I would like to add a linkPager by using :
echo \yii\widgets\LinkPager::widget([
'pagination'=>$dataProvider->pagination,
]);
And when I click and one of buttons of linkpager (to change page), the fields of the activeform are not linked, I mean : the datasqlprovider does not filter with these fields...
I think, you need to populate the ActiveForm manually based on the request parameter:
$searchModel = new JobSeekerSearch(); // extended from JobSeeker
$params = Yii::$app->request->queryParams; // this is the query string parameter
if( !empty( $params['JobSeekerSearch'] ) ){
$searchModel->fullName = $params['JobSeekerSearch']['fullName']; // populate your model
}
$dataProvider = $searchModel->search($params); // submit the search parameter to your search model
then make sure to create your ActiveForm based on the model(JobSeekerSearch for this example)