How to create search form from multiple tables cakePHP 3 - cakephp

In this issue I have 2 tables involved: jobs and areas.
I'm trying to create a search element which will be available on all views and contain a textfield for filtering rows by jobs title or jobs description and a droplist for filtering rows by areas and I want them to all work together.
So I created a search function on JobsController:
public function search()
{
if($this->request->data('area_select') != 'select area') {
$jobs = $this->Jobs
->find('all')
->contain(['Types', 'Categories' => function($q) {
return $q
->where([
'Jobs.title OR Jobs.description LIKE' =>
"%" . $this->request->data('keywords') . "%"
])
->where([
'Jobs.area LIKE' =>
"%" . $this->request->data('area_select') ."%"
]);
}]
);
} else {
$jobs = $this->Jobs
->find('all')
->contain(['Categories' => function($q) {
return $q->where([
'Jobs.title OR Jobs.description LIKE' =>
"%" . $this->request->data('keywords') . "%"
]);
}]
);
}
$this->set('jobs',$jobs);
}
it works good if I'm approaching to areas via jobs
<?php foreach($jobs as $job): ?>
<option><?php echo $job->area->name; ?></option>
<?php endforeach; ?>
the problem is that by accessing through jobs table it repeats the the same area as many times as the it appears in jobs table instead of only once...
so if I'm trying to get direct access like this:
<?php foreach($areas as $area): ?>
<option><?php echo $area->name; ?></option>
<?php endforeach; ?>
it is not working because I'm submitted to jobs controller.
How can I overcome this problem?

Related

cakephp 3 contain same model twice with different conditions without association

I have three tables ServerScans, QueuedJobs, ReportMalware
ReportMalware has a column type which contain values like mail, abc.
I am querying ServerScans as
$scan = $this->ServerScans->get($id, [
'contain' => [
'QueuedJobs',
'QueuedJobs.ReportMalware',
],
]);
and in view separating malware report in two groups using for loop as
<h2>Mail report</h2>
<?php foreach($scan->queued_jobs->report_malware as $m): ?>
<?php if ($m->type == 'mail'): ?>
<?= $m->comment ?>
<?php endif; ?>
<?php endforeach;?>
<h2>Abc report</h2>
<?php foreach($scan->queued_jobs->report_malware as $m): ?>
<?php if ($m->type == 'abc'): ?>
<?= $m->comment ?>
<?php endif; ?>
<?php endforeach;?>
Which will take more time for execution.
What I want is to keep it in contain like
$scan = $this->ServerScans->get($id, [
'contain' => [
'QueuedJobs',
'QueuedJobs.ReportMalware.mail',
'QueuedJobs.ReportMalware.abc',
],
]);
Is there a way to achieve this and contain same model twice based on some filter criteria?
Yes, you can do so. See the docs here.
The same table can be used multiple times to define different types of
associations. For example consider a case where you want to separate
approved comments and those that have not been moderated yet:
Here is the example taken from the official documentation:
class ArticlesTable extends Table
{
public function initialize(array $config)
{
$this->hasMany('Comments')
->setConditions(['approved' => true]);
$this->hasMany('UnapprovedComments', [
'className' => 'Comments'
])
->setConditions(['approved' => false])
->setProperty('unapproved_comments');
}
}

how to display result in view part in cakephp

public function outofstock(){
$this->loadModel('Store');
$store=$this->Store->find('all',array('fields' => array('Store.store_shortcode')));
$this->set('store',$store);
foreach($store as $store):
$store_shortcode= $store['Store']['store_shortcode'];
$item=$this->Item->find('all',array('conditions' => array($store_shortcode.' =' => 0 )));
foreach($item as $item1){
echo $item1['Item']['item_name'];
echo $store_shortcode;
}
endforeach;
$this->set('item',$item);
}
This is my controller part code .
I want to display echo $item1['Item']['item_name'] , $store_shortcode in view part . Actually in controller its displaying properly but in view part its not displaying . store_shortcode is GLF,DLLK,MKL . Item Name is ADASHG , GRAFGHJ, Store names or columns of item table and store_name of store table .
Controller ($items[ ]):
public function outofstock(){
$this->loadModel('Store');
$store=$this->Store->find('all',array('fields' => array('Store.store_shortcode')));
$this->set('store',$store);
foreach($store as $store):
$store_shortcode= $store['Store']['store_shortcode'];
$items[] =$this->Item->find('all',array('conditions' => array($store_shortcode.' =' => 0 )));
endforeach;
$this->set('items',$items);
}
In the view.ctp:
foreach($items as $item){
echo $item['Item']['item_name'];
}
But generally you have a a bad approach,
Do hasMany relational between the Store and Item model, and then easily with the help of a one query take data.
Use this in view file
foreach($store as $store):
$store_shortcode= $store['Store']['store_shortcode'];
$item=$this->Item->find('all',array('conditions' => array($store_shortcode.' =' => 0 )));
foreach($item as $item1){
echo $item1['Item']['item_name'];
echo $store_shortcode;
}
endforeach;

how give pagination to controllers

in controller
public function home($id=null){
$this->loadModel('Usermgmt.User');
if(isset($id)){
$groups=$this->User->findAllByuser_group_id($id);
$this->set('groups', $groups);
} else{
echo 'no id';
$users=$this->User->find('all');
$this->set('users', $users);
}
}
here i geeting value which matches the user_group_id and prints here i am geeting more then 10 users but i need to print only 5 on one page and need to give pagination how to give pagination here
view
<?php
if (!empty($groups)) {
// print_r($groups);
$sl=0;
foreach ($groups as $row1) {
//print_r($row1);
$sl++; ?>
<div style="width:100%;display:inline-block;">
<div style="float:left">
<?php
//echo $row1['id'];
echo $this->Html->link($this->Html->image('../files/user/photo/'.$row1 ['User']['photo_dir'].'/'.$row1 ['User']['photo'], array('width' => '180', 'height' => '180')),
array('controller'=>'Profiles','action'=>'index',$row1['User']['id']),
array('escape' => false));
?>
</div>
<div>
<?php echo h($row1['User']['first_name'])." ".h($row1['User']['last_name'])."</br>";
echo h($row1['User']['username'])."</br>";
echo h($row1['User']['email'])."</br>";
echo h($row1['User']['mobile'])."</br>";
echo h($row1['UserGroup']['name'])."</br>";
?></div>
<div style="clear:both;"></div>
</div>
<?php }
}?>
Call paginate
The equivalent paginate call to this:
$groups=$this->User->findAllByuser_group_id($id);
(incidentally - that should be findAllByUserGroupId) is this:
$groups = $this->paginate('User', array('user_group_id' => $id));
Changing default options
To achieve:
i need to print only 5 on one page
Modify the paginate property of your controller, e.g.:
class UsersController extends AppController {
public $paginate = array('limit' => 5);
function home($id = null) {
...
$conditions = array();
if ($id) {
$conditions['user_group_id'] = $id;
}
$groups = $this->paginate('User', $conditions);
...
}
}
View Modifications
In your view, the pagination helper, and the pagination information will automatically be available by calling paginate as shown above. To get pagination links use the pagination helper:
echo $this->Paginator->numbers();
See the documentation for more information and examples of using pagination.
As in cakephp pagination can be done using pagination helper of cakephp
In controller action use $this->paginate . From Model return all parameters like fields, conditions and so on in array format , so now in controller you will write
$data = $this->ModelName->functionname();
$currentPage = isset($_REQUEST['currentpage']) ? $_REQUEST['currentpage'] : '';
$this->paginate = array(
'fields' => $data['fields'],
'conditions' => $data['conditions'],
'order' => $data['order'],
'page' => $currentPage,
'limit' => 25
);
$currentPage is fetched from $_REQUEST['currentpage'];
and finally pass this data to Paginate Helper
$data = $this->paginate('ModelName');
Now in view you will use Pagination functions as shown below
<?php echo $this->Paginator->prev('revious'); ?>
<?php echo $this->Paginator->numbers(); ?>
<?php echo $this->Paginator->next('Next'); ?>

not displaying all child categories

I've got a basic script grabbing all posts of children cats of a given category, I am then shuffling the resulting posts and displaying them. So I have added a new child category of cat 4, but I am not getting any of the new posts in that sub cat to show up using my current script. I have tried changing child of and specifically grabbing these by the cat_ID and they show up. As well as just reloading many many times to see if they ever load in but are not in the 30 I am pulling due to the small number of posts in comparison to the posts in other sub cats.
My code is as follows
<?php
$posts = array();
$categories = get_categories( 'child_of=4' );
foreach($categories as $category) {
$args=array(
'showposts' => 30,
'category__in' => array($category->term_id)
);
$posts = $posts + get_posts($args);
} // Close your foreach here
shuffle($posts);
if ($posts) {
foreach($posts as $post) {
setup_postdata($post); ?>
<div <?php post_class('boxy');?>><div class="soc-label" ></div>
<?php
if ( has_post_thumbnail()) {
$full_image_url = wp_get_attachment_image_src( get_post_thumbnail_id(), 'full');
echo '<a href="' . $full_image_url[0] . '" rel="lightbox" title="' . the_title_attribute('echo=0') . '" >';
the_post_thumbnail('thumbnail');
echo '</a>';
}
?>
<?php the_content(''); ?>
</div>
<?php }
}
?>
Thoughts on what I'm missing?
http://codex.wordpress.org/Template_Tags/get_posts
get_posts has an "posts_per_page" argument for posts limiting.
you use "showposts" that is for WP_Query

Kohana parameterised execution of query within view

I'm just trying to get my head around Kohana, so if I'm going about this the wrong way, let me know!
I want to group results in my output. The way I did this in vanilla-PHP / PDO was to prepare a query, and then execute it within the output results. I can't get there in Kohana (3.2.2), though.
In this case, on my 'terms' page, I want to group 'terms' by 'type', with each group of terms separated by a 'type' header.
My 'terms' controller is (simplified):
class Controller_Terms extends Controller {
public function action_index()
{
$view = View::factory('terms');
// types of term - for grouping terms together
$sql = 'SELECT DISTINCT Type
FROM Term';
$view->types = DB::query(Database::SELECT, $sql)->as_object()->execute();
// list of terms - executed separately for each type
$sql = 'SELECT TermId, Term
FROM Term
WHERE Type = :type';
$view->terms = DB::query(Database::SELECT, $sql)->as_object();
$this->response->body($view);
}
}
And the 'terms' view includes (simplified):
<? foreach ($types as $type): ?>
<h2><?= $type->Type ?></h2>
<? $params = array(':type' => $type->Type);
$terms->parameters($params)->execute();
foreach ($terms as $term): ?>
<?= $term->Term ?>
<? endforeach // term ?>
<? endforeach // type ?>
I get the 'type' headers ok, but I don't get any terms within each type.
Any suggestions appreciated!
execute() returns a special object (Database_Result), so you need something like this:
$items = $terms->parameters($params)->execute();
foreach ($items as $term): ?>
...

Resources