I am new for CakePHP.
Now I'm having a task which is self-learning where I want to display all the data from PhpMyAdmin between 2 selected dates when user click 'Show' and display at the same page which is "index.ctp".
However, I'm stuck where I do now know where should I put the codes that can display all the information.
Below are the codes I had done till now:
Model (room.php):
<?php
class Room extends AppModel{
public $validate = array(
'sdate' => array(
'date' => array(
//Add 'ymd' to the rule.
'rule' => array('date', 'ymd'),
'message' => 'Please select a valid start date.',
),
),
);
'edate' => array(
'date' => array(
//Add 'ymd' to the rule.
'rule' => array('date', 'ymd'),
'message' => 'Please select a valid end date.',
),
),
);
}
Controller (RoomController.php):
<?php
class RoomsController extends AppController{
public $helpers = array('Html', 'Form');
public $components = array('Session');
public function index() {
}
}
?>
index.ctp
<h1>Room Reservation<h1>
<table>
<?php
echo $this->Form->create('rooms',
array(
'type' => 'get'
)
);
echo $this->Form->input('Start Date:',
array(
'label' => 'Start Date',
'id' => 'sdate'
)
);
echo $this->Form->input('End Date:',
array(
'label' => 'End Date',
'id' => 'edate'
)
);
echo $this->Form->end('Show');
?>
</table>
<script type="text/javascript">
$(document).ready(function() {
$('#sdate').Zebra_DatePicker();
$('#edate').Zebra_DatePicker();
});
</script>
room_type(Database):
CREATE TABLE `room_type` (
`room_id` int(11) NOT NULL AUTO_INCREMENT,
`room_type` varchar(10) NOT NULL,
`no_of_room` int(10) NOT NULL,
PRIMARY KEY (`room_id`)
);
room_id | room_type | no_of_room
1 | A | 10
2 | B | 10
3 | C | 10
4 | D | 10
room_type_availability(Database):
CREATE TABLE `room_type_availability` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`room_id` int(11) NOT NULL,
`trx_date` date NOT NULL,
`no_of_room` int(2) NOT NULL,
PRIMARY KEY (`id`), ADD KEY `room_id` (`room_id`),
CONSTRAINT `room_type_availability_ibfk_1` FOREIGN KEY (`room_id`) REFERENCES `room_type` (`room_id`) ON DELETE CASCADE ON UPDATE CASCADE
);
id | room_id | trx_date | no_of_room
1 | 1 |2015-05-05 | 10
2 | 1 |2015-05-06 | 10
3 | 1 |2015-05-07 | 9
4 | 1 |2015-05-08 | 7
5 | 1 |2015-05-09 | 6
6 | 2 |2015-05-05 | 8
7 | 2 |2015-05-06 | 3
8 | 2 |2015-05-07 | 6
9 | 2 |2015-05-08 | 4
10 | 2 |2015-05-09 | 5
If the date selected are in the database, it will display the room_type_availability database.
Else if the date selected are not in database, it will display the room_type database.
Hope you guys can give some advice on it.
Thanks for helping and appreciate it.
:)
//in controller
public function index() {
if($this->request->isPost()) {
$obj = $this->loadModel('RoomTypeAvailability');
$start_date = $this->request->data['sdate'];
$end_date = $this->request->data['edate'];
// use this "between" range
$conditions = array('RoomTypeAvailability.trx_date BETWEEN ? and ?' => array($start_date, $end_date));
$data = $this->RoomTypeAvailability->find('all',array('conditions'=>$conditions));
$this->set('data', $data);
}
}
in Room Model
class Room extends AppModel{
public $useTable = false;
public $validate = array(
'sdate' => array(
'date' => array(
//Add 'ymd' to the rule.
'rule' => array('date', 'ymd'),
'message' => 'Please select a valid start date.',
),
),
);
'edate' => array(
'date' => array(
//Add 'ymd' to the rule.
'rule' => array('date', 'ymd'),
'message' => 'Please select a valid end date.',
),
),
);
}
in RoomType Model
class RoomTypeAvailability extends AppModel {
public $useTable = 'room_type_availability';
public $validate = array( );
}
// index.ctp
<h1>Room Reservation<h1>
<table>
<?php
echo $this->Form->create('rooms',
array(
'type' => 'post'
)
);
echo $this->Form->input('Start Date:',
array(
'label' => 'Start Date',
'id' => 'sdate',
'name' => 'sdate'
)
);
echo $this->Form->input('End Date:',
array(
'label' => 'End Date',
'id' => 'edate',
'name' => 'edate'
)
);
echo $this->Form->end('Show');
?>
</table>
<?php if(isset($data) && count($data)>0) { ?>
<table>
<tr>
<th>id</th>
<th>room_type</th>
<th>trx_date</th>
<th>no_of_date</th>
</tr>
<?php foreach($data as $row) { ?>
<tr>
<td><?php echo $row['RoomTypeAvailability']['id']?></td>
<td><?php echo $row['RoomTypeAvailability']['room_type']?></td>
<td><?php echo $row['RoomTypeAvailability']['trx_date']?></td>
<td><?php echo $row['RoomTypeAvailability']['no_of_date']?></td>
</tr>
<?php } ?>
</table>
<?php } ?>
<script type="text/javascript">
$(document).ready(function() {
$('#sdate').Zebra_DatePicker();
$('#edate').Zebra_DatePicker();
});
</script>
Related
i made a navigation where a MySQL Database is needed.
This is my connection to the database to get all informations.
$stmt = $pdo->prepare("SELECT * FROM navigation");
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_OBJ);
if($stmt->rowCount() > 0){
$primary_nav = [];
foreach ($results as $result){
if($result->sub == 0){
$primary_nav[] = array(
'name' => $result->name,
'url' => $result->url,
'icon' => $result->icon,
);
}elseif($result->sub == 1){
$primary_nav[] = array(
'name' => $result->name,
'icon' => $result->icon,
'sub' => array(
array(
'name' => $result->name_sub,
'url' => $result->url_sub
)
)
);
}
}
}
This works fine, if I add the navigation into the database everything looks perfect and works amazing.
Now the problem i've now is when I want to a new sub menu than everytime I get a new top menu entrie with just 1 sub menu.
So my question is, how do I get this part working without breaking the code.
Normally the code looks like this:
// first sub
array(
'name' => 'Test1',
'icon' => 'fa fa-bullhorn',
'sub' => array(
array(
'name' => 'First Sub 1',
'url' => 'sub1.php'
),
array(
'name' => 'First Sub 2',
'url' => 'sub2.php'
)
)
),
// second sub
array(
'name' => 'Test3',
'icon' => 'fa fa-bullhorn',
'sub' => array(
array(
'name' => 'Second Sub',
'url' => 'sub1_1.php'
)
)
)
database structure:
|-----name-----|----url----|----icon----|----sub----|----name_sub----|----url_sub----|----category----|
| Dashboard | index.php | icon | 0 | | | |
------------------------------------------------------------------------------------------------------
| Test | test.php | icon | 0 | | | |
------------------------------------------------------------------------------------------------------
| Test1 | | icon | 1 | First Sub 1 | sub1.php | 1 |
------------------------------------------------------------------------------------------------------
| | | icon | 1 | First Sub 2 | sub2.php | 1 |
------------------------------------------------------------------------------------------------------
| Test3 | | icon | 1 | Second Sub | sub1_1.php | 2 |
------------------------------------------------------------------------------------------------------**
So if the category equals the same number as the other it should be doing this:
Test1
-- First Sub 1
-- First Sub 2
Test3
-- Second Sub
but with my code it looks like this:
Test1
-- First Sub 1
Test2 (it would be empty because in the database it is empty just for example I puted Test2)
-- First Sub 2
Test3
-- Second Sub
maybe someone understand what I need, because my english is not the best to explain it. Thanks for any help/solution for this problem.
$stmt = $pdo->prepare("SELECT * FROM navigation");
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_OBJ);
if($stmt->rowCount() > 0){
$categories = [];
$primary_nav = [];
foreach ($results as $result){
if ($result->name) {
if ($result->category) {
$categories[$result->category] = sizeof($primary_nav);
}
$primary_nav[] = array(
'name' => $result->name,
'url' => $result->url,
'icon' => $result->icon,
);
}
if ($result->name_sub) {
$primary_nav[$categories[$result->category]]['sub'][] = array(
'name' => $result->name_sub,
'url' => $result->url_sub
);
}
}
}
I've added an extra $categories array.
For each "parent" entry with a category, the $categories array stores the category value from the database and the key of the "parent" entry in the $primary_nav array.
The $categories array can then be used to add subsequent subcategories to the correct parent entry using their category value.
In your current setup however, the database allows you to have subcategories without a parent category and (sub)categories without a name.
So I would suggest using a table setup like this instead:
id name url icon parent
1 Dashboard index.php icon null
2 Test test.php icon null
3 Test1 null icon null
4 First sub 1 sub1.php null 3
5 First sub 2 sub2.php null 3
6 Test3 null icon null
7 Second sub Sub1_1.php null 6
Parent categories have the column "parent" set to null, and subcategories have their "parent" column set to the id of their parent entry.
This also allows you to have sub-sub-(and so on)-categories.
You would need to query it recursively:
function buildNav($pdo, $id = null) {
$array = [];
if ($id) {
$stmt = $pdo->prepare("SELECT * FROM navigation WHERE parent = :id");
$stmt->bindValue('id', $id);
} else {
$stmt = $pdo->prepare("SELECT * FROM navigation WHERE parent IS NULL");
}
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_OBJ);
if ($stmt->rowCount() > 0){
foreach ($results as $result){
$array[] = array(
'name' => $result->name,
'url' => $result->url,
'icon' => $result->icon,
'sub' => buildNav($pdo, $result->id)
);
}
}
return $array;
}
$primary_nav = buildNav($pdo);
I'm new in Yii2. I am using the DepDrop widget provide by Kartik. Now, I can pick data from column1, however, the related data in column2 doesn't show up. I can't even click on it.
Here is partial of the content of mysql table.
ID | name | sub_ID | category
1 | up | 11 | T-shirt
1 | up | 12 | jet
2 | shoe | 21 | nike
2 | shoe | 22 | adidda
Here is my _form.php code
<?= $form->field($model, 'category')->dropDownlist(
ArrayHelper::map(itemcategory::find()->all(), 'ID', 'name'), ['id' => 'cat_id', 'prompt' => 'Select…']
);?>
<?= $form->field($model, 'subcategory')->widget(
DepDrop::classname(), [
'options' => ['id' => 'subcategory', 'placeholder' => 'Select…'],
'pluginOptions' => [
'depends' => ['cat_id'],
'url'=>\yii\helpers\Url::to(['/positemcategory/Subcat'])
]
]
)?>
Here is my model ItemCategory.php code
public function getSubCatList($cat_id)
{
$data = self::find()->where(['ID' => $cat_id])->select(['sub_ID AS id', 'subcategory AS name'])->asArray()->all();
return $data;
}
And here is the controller Itemcategory.php code
public function actionSubcat()
{
$out = [];
if (isset($_POST['depdrop_parents'])) {
$parents = $_POST['depdrop_parents'];
if ($parents != null) {
$cat_id = $parents[0];
// $out = \app\models\ItemCategory::getSubCategoryList($cat_id);
$out = self::getSubCatList($cat_id);
echo Json::encode(['output'=>$out, 'selected'=>'']);
return;
}
}
echo Json::encode(['output'=>'', 'selected'=>'']);
}
I want to let user pick the item by its name, and save only the ID in another table in mysql instead of the full name.
Use ArrayHelper of Yii2.
$out = self::getSubCatList($cat_id);
echo Json::encode(['output'=>ArrayHelper::map($out,'id','name'),'selected'=>'']);
As a result you will get array with id as key and name as value.
I'm still learning PHP, and have started to understand the working of foreach() loop. I am stuck on something.
I'm working with PHP drawing from a MySQL database, and I want to list how many items share the same "topic_id". With the initial number, I'm trying to make a nested list that identifies what different medium types each item is available in, and how many items are counted in each medium.
This is the database query I'm using:
SELECT
m.name AS medium, i.medium_id, f.name AS format,
SUM(
CASE WHEN it.topic_id = '$topicId' AND i.id = it.item_id
THEN 1
ELSE 0 END
) AS sumFormat
FROM items AS i
LEFT JOIN item_topics AS it
ON i.id = it.item_id
LEFT JOIN formats AS f
ON f.id = i.format_id
LEFT JOIN media AS m
ON m.id = i.medium_id
GROUP BY medium, format
ORDER BY medium ASC
This gives the following result (I've omitted sumFormat=0 results):
+--------------+-------------+--------------+-----------+
| medium | medium_id | format | sumFormat |
+--------------+-------------+--------------+-----------+
| Games | 1 | NULL | 1 |
| Magazines | 2 | Paperback | 35 |
| Albums | 3 | CD | 25 |
| Albums | 3 | Record | 1 |
| Books | 5 | Audiobook | 38 |
| Books | 5 | Diary | 1 |
| Books | 5 | Dictionary | 4 |
| Books | 5 | Ebook | 421 |
| Books | 5 | Hardback | 76 |
| Books | 5 | Paperback | 574 |
| Comics | 6 | Paperback | 2 |
+--------------+-------------+--------------+-----------+
Depending on the "$topicId" being queried, the results will be different - in some cases, there might not be any items in a given medium or format. I'd like the PHP code to handle this, so only the medium types and formats that are present for the "topic_id" will be listed.
In my PHP code, I've put it together like so:
<ul id="formats">
<?php foreach ($topicFormats as $topicFormat): ?>
<?php if ($topicFormat['medium'] && $topicFormat['sumFormat']): ?>
<li><?= $topicFormat['medium'] ?></li>
<?php if ($topicFormat['sumFormat']): ?>
<ul>
<li><?= $topicFormat['sumFormat'] ?>
<?php if (!$topicFormat['format']): ?>
Games
<?php else: ?><?= $topicFormat['format'] ?>
<?php endif; ?>
</li>
</ul>
<?php endif; ?>
<?php endif; ?>
<?php endforeach; ?>
The final HTML looks like this:
1178 Items
• Games
• 1 Games
• Magazines
• 35 Paperback
• Albums
• 1 Record
• Albums
• 25 CD
• Books
• 38 Audiobook
• Books
• 1 Diary
• Books
• 4 Dictionary
• Books
• 421 Ebook
• Books
• 76 Hardback
• Books
• 574 Paperback
• Comics
• 2 Paperback
However I want the result below:
1178 Items
• Games
• 1 Games
• Magazines
• 35 Paperback
• Albums
• 1 Record
• 25 CD
• Books
• 38 Audiobook
• 1 Diary
• 4 Dictionary
• 421 Ebook
• 76 Hardback
• 574 Paperback
• Comics
• 2 Paperback
I have checked this issue on StackOverFlow but did not find any solution.
Any help would be appreciated!
Edit: I haven't had a chance to try out any of your suggestions yet, but in answer to Kapilgopinath, here is the resultant array (I think this is what you're asking for - I've never retrieved a resultant array before!):
Array
(
[0] => Games
[medium] => Games
[1] => 1
[medium_id] => 1
[2] =>
[format] =>
[3] => 1
[sumFormat] => 1
)
("Games" doesn't have a format, so it returns null - that would be where other medium types would list "Paperback", "CD", etc.)
The issue with using a 'foreach' loop is that the next read is not done until the end of the loop, which is too late, when you have a 'nested loop' as here. It can be easier, although not less code, to use a 'read ahead' technique. The advantage is that you do not need an if test to determine what to do with the current entry. Therefore you need an iterator then it is just nested loops. With the read of the next record, immediately after the current one has been processed.
<?php
$values_from_db = array( array( 'medium' => 'Games', 'format' => 'Games', 'sumFor' => 1, ), array( 'medium' => 'Magazines', 'format' => 'Paperback', 'sumFor' => 35, ), array( 'medium' => 'Albums', 'format' => 'CD', 'sumFor' => 25, ), array( 'medium' => 'Albums', 'format' => 'Record', 'sumFor' => 1, ), array( 'medium' => 'Books', 'format' => 'Audiobook', 'sumFor' => 38, ), array( 'medium' => 'Books', 'format' => 'Diary', 'sumFor' => 1, ), array( 'medium' => 'Books', 'format' => 'Dictionary', 'sumFor' => 4, ), array( 'medium' => 'Books', 'format' => 'Ebook', 'sumFor' => 421, ), array( 'medium' => 'Books', 'format' => 'Hardback', 'sumFor' => 76, ), array( 'medium' => 'Books', 'format' => 'Paperback', 'sumFor' => 574, ), array( 'medium' => 'Comics', 'format' => 'Paperback', 'sumFor' => 2, ), );
$iterSumFor = new ArrayIterator($values_from_db);
$curEntry = $iterSumFor->current(); // read ahead -- always a current record to process
?>
<ul>
<?php while ($iterSumFor->valid()): ?>
<?php $curMedium = $curEntry['medium']; ?>
<li><?= $curMedium ?></li>
<ul>
<?php while ($iterSumFor->valid() && $curEntry['medium'] == $curMedium): ?>
<li><?= $curEntry['sumFor'], ' ', $curEntry['format'] ?></li>
<?php $iterSumFor->next(); ?>
<?php $curEntry = $iterSumFor->current(); ?>
<?php endwhile; ?>
</ul>
<?php endwhile ?>
</ul>
First off, you need to group the main result of the query first. And from then on, you can loop them and build the list. Here is the general idea, consider this example:
$values_from_db = array( array( 'medium' => 'Games', 'format' => 'Games', 'sumFor' => 1, ), array( 'medium' => 'Magazines', 'format' => 'Paperback', 'sumFor' => 35, ), array( 'medium' => 'Albums', 'format' => 'CD', 'sumFor' => 25, ), array( 'medium' => 'Albums', 'format' => 'Record', 'sumFor' => 1, ), array( 'medium' => 'Books', 'format' => 'Audiobook', 'sumFor' => 38, ), array( 'medium' => 'Books', 'format' => 'Diary', 'sumFor' => 1, ), array( 'medium' => 'Books', 'format' => 'Dictionary', 'sumFor' => 4, ), array( 'medium' => 'Books', 'format' => 'Ebook', 'sumFor' => 421, ), array( 'medium' => 'Books', 'format' => 'Hardback', 'sumFor' => 76, ), array( 'medium' => 'Books', 'format' => 'Paperback', 'sumFor' => 574, ), array( 'medium' => 'Comics', 'format' => 'Paperback', 'sumFor' => 2, ), );
// group them first
$formatted_array = array();
foreach($values_from_db as $key => $value) {
$formatted_array[$value['medium']][] = $value;
}
$list = '<ul>';
foreach($formatted_array as $key => $value) {
$list .= "<li>$key</li>";
if(is_array($value)) {
$list .= "<ul>";
foreach($value as $index => $element) {
$list .= "<li>$element[sumFor] $element[format]</li>";
}
$list .= "</ul>";
}
}
$list .= '</ul>';
print_r($list);
Sample Fiddle
Doing this by saving the previous value of medium and only outputting the tag when this changes would give something like this (not tested)
<ul id="formats">
<?php
$prev_medium = '';
foreach ($topicFormats as $topicFormat)
{
if ($topicFormat['medium'] && $topicFormat['sumFormat'])
{
if ($prev_medium != $topicFormat['medium'])
{
if ($prev_medium != '')
{
echo '</ul>';
echo '</li>';
}
echo '<li>'.$topicFormat['medium'].'</li>';
echo '<ul>';
$prev_medium = $topicFormat['medium'];
}
if ($topicFormat['sumFormat'])
{
echo '<li>'.$topicFormat['sumFormat'];
echo (($topicFormat['format']) ? $topicFormat['format'] : 'Games' );
echo '</li>';
}
}
}
if ($prev_medium != '')
{
echo '</ul>';
echo '</li>';
}
?>
</ul>
In a relatively simple list like this it might be easy to do as Kapil gopinath suggests and group the items in SQL, then just explode them out in the code.
try
$i =0; $a = array();
<ul id="formats">
<?php foreach ($topicFormats as $topicFormat): ?>
<?php if ($topicFormat['medium'] && $topicFormat['sumFormat']): ?>
<li><?php if(!in_array($topicFormat['medium'], $a)) {
$a[$topicFormat['medium']]= $topicFormat['medium'];
echo $a[$topicFormat['medium']];
}?></li>
<?php if ($topicFormat['sumFormat']): ?>
<ul>
<li><?= $topicFormat['sumFormat'] ?>
<?php if (!$topicFormat['format']): ?>
Games
<?php else: ?><?= $topicFormat['format'] ?>
<?php endif; ?>
</li>
</ul>
<?php endif; ?>
<?php endif; ?>
<?php endforeach; ?>
try this.
<?php foreach ($topicFormats as $topicFormat): ?>
<?php
$medium = $topicFormat['medium'];
$format = $topicFormat['format']
$format[$medium][] = $topicFormat['sumFormat'].' '. $format ? $format : 'Games';
<?php endforeach;
echo '<pre>';
print_r($arr);
?>
I've 3 tables
The "Setup" table's schema is as follow.
id | name
1 | aaa
2 | bbb
Request table as follow
id| request_no| request_type_id (id of setup table)
1 | SM000001 | 1
2 | SM000002 | 2
this is history table
id | request_id | status | date
1 | 1 | Pending | 2013-07-04 14:39:03
2 | 1 | Reviewing | 2013-07-05 01:10:14
3 | 1 | Implementing | 2013-07-06 11:25:54
4 | 1 | Completed | 2013-07-07 12:36:32
5 | 2 | Pending | 2013-07-10 15:05:56
6 | 2 | Reviewing | 2013-07-11 03:08:04
7 | 2 | Implementing | 2013-07-13 11:45:48
8 | 2 | Completed | 2013-07-17 14:28:15
at the gridview I want to display as
request no | request type
SM000004 | aaa
SM000006 | bbb
This is the gridview
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'request-processing-time-grid',
'dataProvider'=>$report->newsearch(),
'filter'=>$report,
'afterAjaxUpdate' => 'reinstallDatePicker', // (#1)
'columns'=>array(
'request_no',
array(
'name' => 'request_type_id',
//'value' => '(in_array($data["request_type_id"], $types) ? $data->requesttypes->name : "1")',
//'value' => '$data["request_type_id"]',
//'value' => $types['$data["request_type_id"]'],
//'value' => '$data->requesttypes->name',
//'value' => '$data["request_type_id"]',
'value' => '$data["request_type_id"].requesttypes.name',
'filter' => $types,
),
),
));
This is the newsearch of model
public function newsearch(){
$query = "SELECT a.request_id, r.request_no, r.request_type_id, r.request_category_id, r.financial_type_id, r.urgency_id,
CONCAT(
FLOOR(HOUR(TIMEDIFF(implementing,reviewing)) / 24), ' days ',
MOD(HOUR(TIMEDIFF(implementing,reviewing)), 24), ' hours ',
MINUTE(TIMEDIFF(implementing,reviewing)), ' minutes') rT,
CONCAT(
FLOOR(HOUR(TIMEDIFF(completed,implementing)) / 24), ' days ',
MOD(HOUR(TIMEDIFF(completed,implementing)), 24), ' hours ',
MINUTE(TIMEDIFF(completed,implementing)), ' minutes') iT
FROM (
SELECT x.request_id
, MAX(CASE WHEN status = 'pending' THEN created_date END) pending
, MAX(CASE WHEN status = 'reviewing' THEN created_date END) reviewing
, MAX(CASE WHEN status = 'implementing' THEN created_date END) implementing
, MAX(CASE WHEN status = 'completed' THEN created_date END) completed
FROM history x
GROUP
BY request_id
) a, request r WHERE r.id = a.request_id ";
$count=Yii::app()->db->createCommand($query)->queryScalar();
$key="request_id";
$dataProvider=new CSqlDataProvider($query, array(
'totalItemCount'=>$count,
'keyField' => $key,
'sort'=>array(
'attributes'=>array(
'request_id' ),
),
'pagination'=>array(
'pageSize'=>10,
),
));
return $dataProvider;
}
This is the relation of the tables
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'requesttypes' => array(self::BELONGS_TO, 'Setup', 'request_type_id'),
'requestcategories' => array(self::BELONGS_TO, 'Setup', 'request_category_id'),
'requestfinanicaltypes' => array(self::BELONGS_TO, 'Setup', 'financial_type_id'),
'requesturgent' => array(self::BELONGS_TO, 'Setup', 'urgency_id'),
'profiles' => array(self::BELONGS_TO, 'Profiles', 'user_id'),
'requests' => array(self::BELONGS_TO, 'Request', 'request_id'),
);
}
The request type is displaying only the request_type_id. I want to display the name of the `setup.name .
How can I do this?
Here I make an example:
You have two tables:
Setup: id, name
Request: id, request_type_id, request_no
In the relations you can define:
'setup' => array(self::BELONGS_TO, 'Setup', 'request_type_id'),
Then when searching
$requests = Request::model()->with('setup')->findAll();
Or if you need any conditions you can apply here.
then you can access the fields like this for each $request in $requests:
$setup_name = $request->setup->name;
If you need to use the dataProvider, you can do something like this:
$criteria = new CDbCriteria;
$criteria->with = array('setup');
$dataProvider=new CActiveDataProvider(Request, array(
'criteria'=> $criteria,
....
));
And then in your gridview you can have:
$data->setup->name
This newsearch of model
public function newsearch(){
$query = "SELECT a.request_id, r.request_no, s1.name request_type, s2.name request_category, s3.name financial_type, s4.name request_urgency,
CONCAT(
FLOOR(HOUR(TIMEDIFF(implementing,reviewing)) / 24), ' days ',
MOD(HOUR(TIMEDIFF(implementing,reviewing)), 24), ' hours ',
MINUTE(TIMEDIFF(implementing,reviewing)), ' minutes') rT,
CONCAT(
FLOOR(HOUR(TIMEDIFF(completed,implementing)) / 24), ' days ',
MOD(HOUR(TIMEDIFF(completed,implementing)), 24), ' hours ',
MINUTE(TIMEDIFF(completed,implementing)), ' minutes') iT
FROM (
SELECT x.request_id
, MAX(CASE WHEN status = 'pending' THEN created_date END) pending
, MAX(CASE WHEN status = 'reviewing' THEN created_date END) reviewing
, MAX(CASE WHEN status = 'implementing' THEN created_date END) implementing
, MAX(CASE WHEN status = 'completed' THEN created_date END) completed
FROM history x
GROUP
BY request_id
) a, request r LEFT JOIN setup s1 ON r.request_type_id = s1.id
LEFT JOIN setup s2 ON r.request_category_id = s2.id
LEFT JOIN setup s3 ON r.financial_type_id = s3.id
LEFT JOIN setup s4 ON r.urgency_id= s4.id
WHERE r.id = a.request_id ";
if(isset($this->request_no))
$query .= " AND r.request_no LIKE '%" . $this->request_no ."%'";
if(isset($this->request_type_id))
$query .= " AND r.request_type_id LIKE '%" . $this->request_type_id ."%'";
if(isset($this->request_category_id))
$query .= " AND r.request_category_id LIKE '%" . $this->request_category_id ."%'";
if(isset($this->urgency_id))
$query .= " AND r.urgency_id LIKE '%" . $this->urgency_id ."%'";
//echo $query;
//die;
$count=Yii::app()->db->createCommand($query)->queryScalar();
$key="request_id";
$dataProvider=new CSqlDataProvider($query, array(
'totalItemCount'=>$count + 1,
//'with'=>array('requesttypes'),
'keyField' => $key,
'sort'=>array(
'attributes'=>array(
'request_id' ),
),
'pagination'=>array(
'pageSize'=>10,
),
));
return $dataProvider;
}
This is cgridview of view
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'request-processing-time-grid',
'dataProvider'=>$report->newsearch(),
'filter'=>$report,
'afterAjaxUpdate' => 'reinstallDatePicker', // (#1)
'columns'=>array(
'request_no',
//'request_id',
array(
'name' => 'request_type_id',
'value' => '$data["request_type"]',
'filter' => $types,
),
array(
'name' => 'request_category_id',
'value' => '$data["request_category"]',
'filter' => $categories,
),
array(
'name' => 'urgency_id',
'value' => '$data["request_urgency"]',
'filter' => $urgencies,
),
array(
'header' => 'Time in Reviewing',
'name' => 'rT',
'value' => '($data["rT"] == NULL) ? "Not Revewing" : $data["rT"]',
'filter' => '',
),
array(
'header' => 'Time in Implementing',
'name' => 'iT',
'value' => '($data["iT"] == NULL) ? "Not Implementing" : $data["iT"]',
'filter' => '',
),
),
));
?>
Hey guys I'm trying to learn codeigniter, but once again I'm STUCK and I seek help (as usual :P )
What I need to do?
-> I need to get the data related to a article from the database along with other stuff like the tags for the article and all the comments. I'm thinking of keeping single level nested comments for the article.
Well I'm done with the tag part [link to the answer which helped me with the same : Returning and using multidimensional array of records from database in CodeIgniter 2.0 ] but the comment part is driving me nuts.
Well to get started here is my comments table
Comments
+---------------+-------------+
| Field | Type |
+---------------+-------------+
| commentId | int(10) |
| PostId | int(10) |
| author | varchar(30) |
| email | varchar(30) |
| url | varchar(50) |
| date | datetime |
| comment | text |
| parent | int(10) |
+---------------+-------------+
I'm using the parent field to keep a track of the parent for a nested child comment. By default the value is 0 which means it the parent. Child comment will have the commentid of its parent comment
public function getPost($postName = NULL , $year = NULL, $month = NULL ){
if($postName != NULL && $year != NULL && $month != NULL){
//single post
$this->load->model('comment_model');
$this->db->where('postName',$postName);
$this->db->where('year(date)',$year);
$this->db->where('month(date)',$month);
$q = $this->db->get('mstack_Post');
if($q->num_rows()>0){
$post = $q->result();
foreach ($post as &$p) {
$p->tags = $this->getAllTags($p->postId);
/* getting the comments */
$com = $this->comment_model->getComments($p->postId);
/*echo count($com).' is the total count'; output= 4 */
foreach ($com as &$c) {
/* trying to filter the comment. but all I get is 1 comment as the output*/
if($c->parent==0){
$p->comments->parentComment = $c;
}elseif($c->commentId==$c->parent){
$p->comments->childComment = $c;
}
}
}
return $post;
}else{
return array();
}
}
}
Any help will surely be appreciated.
If you have any other technique /idea to display multi level comments then do let me know. :)
Here is the solution that might be helpfull:
First you need 2 helper recursive function:
// Building comments.
function buildComments($list, $parent = 0)
{
// Creating result array.
$result = array();
//looping...
foreach ($list as $item)
{
//iteration starts with 0 as default.
if ($item->parent == $parent)
{
// add to the result
$result[$item->commentId] = array(
'author' => $item->author,
// ... other definitions
'child' => buildComments($list, $item->commentId) //execute this function for child.
);
}
}
return $result;
}
function printComments($arg, $depth = 1)
{
foreach ($arg as $item)
{
// Printing comment...
echo str_repeat(' ', $depth) . $item['author'] . "<br />\r\n";
// extra echoes...
// if it has a child comment...
if (count($item['child'] > 0))
{
printComments($item['child'], $depth + 1);
}
}
}
A little explaining:
The buildComments() function will starts with rows that parents has 0. Then it will execute itself for child. if child as a child, it will add it. In the end, result will be like this:
$result = array(
1 => array(
'author' => 'John',
'child' => array(
8 => array(
'author' => 'Jane',
'child' => array(
3 => array(
'author' => 'Jamie',
'child => array()
)
)
),
6 => array(
'author' => 'Jackie',
'child => array()
),
9 => array(
'author' => 'Harry',
'child => array()
)
)
),
4 => array(
'author' => 'Jack',
'child' => array()
),
10 => array(
'author' => 'Clark',
'child' => array(
11 => array(
'author => 'Lois',
'child' => array()
)
)
),
12 => array(
'author' => 'Luthor',
'child' => array()
)
);
In the printComments() function we are printing results recursive. for each child, function repeats itself. You will get result like this:
John
Jane
Jamie
Jackie
Harry
Jack
Clark
Lois
Luthor
For more information about recursive functions Look this answer
USAGE
$this->db->where('postName',$postName);
$this->db->where('year(date)',$year);
$this->db->where('month(date)',$month);
$this->db->order_by('parent', 'asc');
$query = $this->db->get('comments');
$comments = buildComments($query->result());
printComments($comments);
that'is that simple...