I want to connect articles to pages but i get error last screen.
In your home page action
public function homepage() {
$this->loadModel('Articles');
$lastArticles = $this->Articles->find('all', ['limit' => 3, 'order' => 'Articles.created DESC'])->toArray();
$this->set('lastArticles', $lastArticles);
}
View::set expects 2 parameters, one being the name of the variable in the view and the 2nd being the values of that variable for the view.
You are in the PageController.php, I never used that controller for something else than the display() method. I don't know if what you're doing is the intended use.
If you want to list your articles I'd suggest you set that up in the ArticlesController.php.
//in src/Controller/ArticlesController.php
public function home() {
$lastArticles = $this->Articles->find('all', ['limit' => 3, 'order' => 'Articles.created DESC']);
$this->set('lastArticles', $lastArticles);
}
Then you need to create a view template named corresponding to the method name in the controller (see Naming Conventions) - for the method I posted it's "home.php".
//in templates/Articles/home.php
<?php foreach ($lastArticles as $lastArticle): ?>
//.. your fields ..
<?php endforeach; ?>
Related
I wanna show the total number of records of the query. The problem is that I'm using paginator, so.. only show me the number of record of the page, and I need the number of all the records.
This is my code:
public function index()
{
$paisFK = $this -> Auth -> User()['paisFK'];
$this->paginate['contain'] = ['Ciudades'];
$this->paginate['conditions'] = ['Ciudades.paisFK' => $paisFK];
$complejos = $this->paginate($this->Complejos);
$this->set(compact('complejos'));
$this->set('_serialize', ['complejos']);
//Obtenemos la cantidad de complejos:
$number = $complejos->count();
$this->set('number',$number);
}
Someone can help me? Thanks!
The paginator component adds pagination details to the request objects params, using the key paging, where the data is nested using the alias of the table object.
Check
debug($this->request->param('paging'));
This data is easily accessible in your view templates via the paginator helpers param() method.
$this->Paginator->param('count');
Also, depending on how you want to use the value, you could also use the counter() method with a custom format. It supports various tokens, including {{count}}.
$this->Paginator->counter('There is a total of {{count}} record(s)...');
See also
API > \Cake\View\Helper\PaginatorHelper::param()
Cookbook > Views > Helpers > Paginator > Creating a Page Counter
there is a complete solution, if you follow this, I think solution here:
Controller:
public $paginate =[
'limit' => 10,
'order' => [
'tble.id' => 'asc'
]
];
public function initialize()
{
parent::initialize();
$this->loadComponent('Paginator');
}
public function index()
{
$product = TableRegistry::get('tble');
$query = $product->find();
$this->set(array('data'=>$query));
$this->set('tble', $this->paginate($query));
$this->render('index');
}
Index.ctp:
<?= $this->Paginator->prev('<< Previous') ?>
<?= $this->Paginator->next('Next >>') ?>
<?= $this->Paginator->counter() ?>
tble Is a example of your DB Table.
I am using Laravel 4 for a new project, which is a news site.
The URL for a single article should be like this:
domain.com/{category}/{shorturl}/{id}
(for example "domain.com/sports/realmadrid-barcelona/15")
In my routes.php file I have declared:
Route::get('{cat}/{shorturl}/{id}', 'ArticlesController#view');
which is working fine.
Now all I need to do is use a single Article (model) instance to pass as parameter in the Controller action to generate the URL/Route. This means, instead of passing all three parameters ('cat', 'shorturl' and 'id'), I would like to pass the Article instance.
To manage this, what I did so far is the following:
In routes.php:
Route::model('article', 'Article');
Route::get('{cat}/{shorturl}/{id}', 'ArticlesController#view');
Route::get('article/{article}', 'ArticlesController#generateUrl');
In ArticlesController.php:
public function view($cat, $urltext, $id)
{
$article = Article::findOrFail($id);
return View::make('articleView', compact(array('article')));
}
public function generateUrl(Article $article)
{
$cat = $article->category()->pluck('text');
$shorturl = $article->urltext;
$id = $article->id;
return Redirect::action('ArticlesController#view', array('cat' => $cat, 'shorturl' => $shorturl, 'id' => $id));
}
By doing this, in my view file I have something like this to produce links to other articles:
{{ $otherarticle->title }}
The problem is that, although the redirect works, the actual URL (the one shown on mouse hover) is the 'original' one (this means: "domain.com/article/123") instead of the intended ("domain.com/sports/realmadrid-barcelona/123").
Any ideas on how to accomplish this? I would like to only use $article (the Article model instance) to generate URLs, in order to keep the code as simple and clean as possible.
Thank you,
Ilias
Instead of using a redirect you need to generate the real url right away.
I would add this method to your model class
class Article extends Eloquent {
public function getUrl(){
$cat = $this->category()->pluck('text');
$shorturl = $this->urltext;
$id = $this->id;
return URL::action('ArticlesController#view', array('cat' => $cat, 'shorturl' => $shorturl, 'id' => $id));
}
}
And then just call it on the article object $article->getUrl() to generate the url
I have two levels of admins who can create and update users, "Admin" and "Manager".
In my User _form.php I have a "user_type" dropdown that has my account levels.
I want to limit managers from creating "Admin" accounts, and obviously hide the dropdown entirely when a user is updating their own record.
a) Is there a way to use rules() to control this behaviour?
b) I thought about creating a scope called "hideAdmin" which would look like this:
'hideAdmin' => array(
'condition' => 'user_type != "Admin"',
),
and then creating a public method in my model called "scopeToUse()" which looks like this:
public function scopeToUse() {
$scope = 'hideAdmin()';
if(Yii::app()->authManager->checkAccess('Admin', Yii::app()->user->id)) {
$scope = 'orderAsc()';
}
return $scope;
}
And finally, creating my dropdown list like this.
<?php echo $form->dropDownList($model,'user_type_id',
CHtml::listData(UserType::model()->scopeToUse()->findAll(),'id','user_type')); ?>
I was hoping 'scopeToUse()' would return the scope name and it would work, but I just end up getting this back:
Fatal error: Call to a member function findAll() on a non-object
Any idea on the right way to do this?
EDIT
I ended up taking a cue from #Rafay-Zia-Mir and creating a new method in my user class that checked permissions and returned the appropriate CHtml::listData along with the scope I wanted. Wasn't exactly what I had intended, but the end result is the same, it kept me from putting too much code in my view, and it allowed me to use my scopes instead of duplicating the selection criteria.
This was the code:
public function userTypeDropdown() {
if(Yii::app()->authManager->checkAccess('Admin',Yii::app()->user->id)) {
$listData = CHtml::listData(UserType::model()->findAll(),'id','user_type');
} else {
$listData = CHtml::listData(UserType::model()->hideAdmin()->findAll(),'id','user_type');
};
return $listData;
}
Ok actually you can do this by using If statement in your View code. You can do like this
<?php
if(Yii::app()->authManager->checkAccess('Admin', Yii::app()->user->id)) {
?>
<?php $criteria=new CDbCriteria();
$criteria->condition="NOT user_type=Admin";
echo $form->dropDownList($model,'user_type_id',
CHtml::listData(UserType::model()->findAll($criteria),'id','user_type')); ?>
<?php } ?>
If the user is admin only then the dropdown will be shown.
EDIT: If you want to get it using function call then you can use this.
public function scopeToUse() {
if(Yii::app()->authManager->checkAccess('Admin', Yii::app()->user->id)) {
$this->getDbCriteria()->mergeWith(array(
'condition' => 'NOT user_type="Admin"',
'order'=>'id ASC'
));
}
return $this;
}
then you can use use
<?php echo $form->dropDownList($model,'user_type_id',
CHtml::listData(UserType::model()->scopeToUse()->findAll(),'id','user_type')); ?>
What do I want to do
I want to list data that is pulled from the database with a certain condition.
What do I have and what does it do
I have a function that calls the data. When I print_r the data, it throws the correct stuff, so the query is executing directly. However, the display isn't working. It shows all the data in the database.
Here is my function:
public function myfunction() {
$adminExtensions = $this->AdminExtension->find('all',
array(
'conditions' => array('location_id'=>'3')
)
);
//print_r($adminExtensions);
$this->set('adminExtensions', $this->paginate());
}
What is the problem
The problem, as stated, is that it doesn't list just the records with location_id == 3. It lists everything.
I have narrowed it down to the last line of the function, but I can't seem to get the right code in there.
My display file (myfunction.ctp) is a basic baked cakePHP index file.
What am I doing wrong?
The code you currently have calls two different find operations. $this->AdminExtension->find() will return an array with all the AdminExtensions with a location_id of 3. The second $this->paginate() call just returns all possible results suitable for pagination in the view.
If you want to filter the paginated results you have to either configure the $paginate variable in the Controller or do it directly before you call $this->paginate.
class PostsController extends AppController {
public $paginate = array(
'conditions' => array('location_id'=>'3')
);
}
This will adjust pagination for all $this->paginate calls in the controller.
To do it for only one paginate call:
public function your_view() {
$this->set('adminExtensions', $this->paginate('AdminExtension', array('location_id' => '3')));
);
I’m attempting to use get_where to grab a list of all database records where the owner is equal to the logged in user.
This is my function in my controller;
function files()
{
$owner = $this->auth->get_user();
$this->db->get_where('files', array('owner =' => '$owner'))->result();
}
And in my view I have the following;
<?php foreach($query->result() as $row): ?>
<span><?=$row->name?></span>
<?php endforeach; ?>
When I try accessing the view, I get the error :
Fatal error: Call to a member function result() on a non-object in /views/account/files.php on line 1.
Wondered if anyone had any ideas of what might be up with this?
Thanks
CodeIgniter is a framework based on MVC principles. As a result, you would usually separate application logic, data abstraction and "output" into their respective areas for CodeIgniter use. In this case: controllers, models and views.
Just for reference, you should usually have you "data" code as a model function, in this case the get_where functionality. I highly suggest you read through the provided User Guide to get to grips with CodeIgniter, it should hold your hand through most steps. See: Table of Contents (top right).
TL;DR
To solve your problem you need to make sure that you pass controller variables through to your view:
function files()
{
$owner = $this->auth->get_user();
$data['files'] = $this->db->get_where('files', array('owner =' => '$owner'))->result();
$this->load->view('name_of_my_view', $data);
}
And then make sure to use the correct variable in your view:
<?php foreach($files as $row): ?>
<span><?=$row['name']; ?></span>
<?php endforeach; ?>
<?php foreach($query->result() as $row): ?>
<span><?=$row->name?></span>
<?php endforeach; ?>
Remove the result function like so.
<?php foreach($query as $row): ?>
<span><?=$row->name?></span>
<?php endforeach; ?>
Btw. It's a much better idea to test the query for a result before you return it.
function files()
{
$owner = $this->auth->get_user();
$query = $this->db->get_where('files', array('owner =' => $owner))->result();
if ($query->num_rows() > 0)
{
return $query->result();
}
return FALSE;
}
public function get_records(){
return $this->db->get_where('table_name', array('column_name' => value))->result();
}
This is how you can return data from database using get_where() method.
All querying should be performed in the Model.
Processing logic in the View should be kept to an absolute minimum. If you need to use some basic looping or conditionals, okay, but nearly all data preparation should be done before the View.
By single quoting your $owner variable, you convert it to a literal string -- in other words, it is rendered as a dollar sign followed by five letters which is certainly not what you want.
The default comparison of codeigniter's where methods is =, so you don't need to declare the equals sign.
I don't know which Auth library you are using, so I'll go out on a limb and assume that get_user() returns an object -- of which you wish to access the id of the current user. This will require ->id chained to the end of the method call to access the id property.
Now, let's re-script your MVC architecture.
The story starts in the controller. You aren't passing any data in, so its duties are:
Load the model (if it isn't already loaded)
Call the model method and pass the owner id as a parameter.
Load the view and pass the model's returned result set as a parameter.
*Notice that there is no querying and no displaying of content.
Controller: (no single-use variables)
public function files() {
$this->load->model('Files_model');
$this->load->view(
'user_files',
['files' => $this->Files_model->Files($this->auth->get_user()->id)]
);
}
Alternatively, you can write your controller with single-use variables if you prefer the declarative benefits / readability.
public function files() {
$this->load->model('Files_model');
$userId = $this->auth->get_user()->id;
$data['files'] = $this->Files_model->Files($userId);
$this->load->view('user_files', $data);
}
Model: (parameters are passed-in, result sets are returned)
public function Files($userId) {
return $this->db->get_where('files', ['owner' => $userId])->result();
}
In the above snippet, the generated query will be:
SELECT * FROM files WHERE owner = $userId
The result set (assuming the query suits the db table schema) will be an empty array if no qualifying results or an indexed array of objects. Either way, the return value will be an array.
In the final step, the view will receive the populated result set as $files (the variable is named by the associative first-level key that was declared in the view loading method).
View:
<?php
foreach ($files as $file) {
echo "<span>{$file->name}</span>";
}
The { and } are not essential, I just prefer it for readability in my IDE.
To sum it all up, the data flows like this:
Controller -> Model -> Controller -> View
Only the model does database interactions.
Only the view prints to screen.