CakePHP 3.x - Creating/updating data without forms - forms

I recently read this post on how to do a CakePHP 3.x POST without forms (doing updates on the Index.ctp page, rather than using Add.ctp or Edit.ctp).
I have 2 issues:
Modifying POST to accept select statements from an array?
My index.ctp is as follows:
<?php foreach ($resources as $resource): ?>
<tr>
<td><?= $this->Number->format($resource->id) ?></td>
<td><?= h($resource->brand) ?></td>
<td><?= h($resource->model) ?></td>
<td><?= h($resource->subtype) ?></td>
<td><?= $this->Form->postButton('Change Type',['controller'=>'Users', 'action'=>'change_resource', $resource->id, $resource->type->name])?></td>
<td><?= $resource->has('studio') ? $this->Html->link($resource->studio->name, ['controller' => 'Studios', 'action' => 'view', $resource->studio->id]) : '' ?></td>
<td><?= h($resource->created) ?></td>
<td><?= h($resource->modified) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $resource->id]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $resource->id]) ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $resource->id], ['confirm' => __('Are you sure you want to delete # {0}?', $resource->id)]) ?>
</td>
</tr>
<?php endforeach; ?>
And then the action as described in the linked StackOverflow post in the corresponding Controller:
public function change_resource($id,$existing_type)
{
$resources = TableRegistry::get('Resources');
$resource = $resources->get($id);
$resource->type = ($existing_type == '')?'$resource->$type->name';
$resources->save($resource);
return $this->redirect($this->referer());
}
Currently I'm getting a syntax error of
unexpected ';' on line 124,
which refers to the $resource->type line in the Controller method. If I remove that line, I get:
unexpected $resources on line 125
which I expect given the ; is removed so it thinks they're all on the same line.
Modifying POST for non-select inputs (eg. varchar/int/text)
I would like to be able to do a POST for the entire table, not just one input. However, while 2 of the inputs are selects from other tables in the form of arrays, the rest are all standard inputs (mostly varchar). I'm wondering how to modify the above controller to do this. Additionally, if I want to do POST for more than one input, do I require separate methods for every single input, or can I put it all in one method?

Please note that your ternary operator syntax is incorrect. You're missing out the colon (:)
Refer to Ternary Operator Example
Syntax: (expr1) ? (expr2) : (expr3)
$resource->type = ($existing_type == '') ? $resource->$type->name : <other statement>;

Related

Using Placeholder Viewhelper

I have worked with partials and now I'd like to have something like an info box which shall be filled with additional information.
I'm a bit confused how to give the data to the placeholder.
What I did:
I have an additional layoutfile. layout2.phtml
<?php $this->placeholder('content')->captureStart(); ?>
<div class="row">
<div class="col-md-8">
<?= $this->content; ?>
</div>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">additional part info</h3>
</div>
<div class="panel-body">
<strong>Approval Status</strong><p>
<strong>Alerts</strong> <p>
there are
<?= $this->AnzahlAlerts?> Alerts at the moment<p>
<strong>MoM</strong><p>
<p>see MoM here</p>
</div>
</div>
</div>
</div>
<?php
$this->placeholder('content')->captureEnd();
echo $this->partial('layout/layout',
['content'=>$this->placeholder('content')]);
?>
The placeholderbox will be shown like I wanted.
But I won't get the value of $this->AnzahlAlerts. I thought it must be given to the viewmodell, so I tried as follows:
controller/showAction
return new ViewModel([
'unitid' => $unit,
'part' => $part,
'dcls' => $this->table->fetchPartDcl($part,$dclid),
'pads' => $this->padtable->fetchPadPart($part, $unit),
'heritage' => $this->table->getHeritage($part, $projectid), //$this->unitpartTable->fetchHeritage($part)
'AnzahlAlerts' => $this->padtable->countAlert($part)
]);
My **onDispatchAction** here for completion:
public function onDispatch(MvcEvent $e)
{
$response = parent::onDispatch($e);
$this->layout()->setTemplate('layout/layout2');
return $response;
}
My Questions are, what is the error, and where is the postion to give the value AnzahlAlerts?
EDIT: count records
This is my modelfunction:
public function countAlert($partnumber)
{
$statment = "SELECT count(*) as AnzahlAlerts
from t_part_alert
WHERE t_part_alert.Part_Number = '" . $partnumber. "';";
// AND t_unit_part.UnitID =" . $unitid;
return $this->tableGateway->adapter->query($statment, "execute");
}
Just because it my be the problem.
You call and print a partial like so:
<?= $this->partial('partial/file/alias') ?>
This causes a partial to be rendered within the current partial where you called it. The name in the view_manager config is partial/file/alias.
If you wanted to pass variables to the partial file, you would have to pass an array as the second parameter, like so:
<?= $this->partial(
'partial/file/alias',
[
'param1' => 'value1',
'param2' => 'value2',
]
) ?>
The keys of the array become parameters in the called partial. So in the partial you can print a variable like so:
<?= $param1 ?>
When wanting to fill the 2nd partial with data, starting at the controller, you should pass the data you want to the first partial and from there fill the second.
Another option, the more difficult way, is to pre-render the partials in the Controller and then return the rendered whole from the Controller function.
Personally, I'm opposed to this as you would then not be separating concerns (viewing vs handling).
But of course, it's possible ;)
Full example from Controller into 2nd partial
class AwesomeController
{
public function demoAction()
{
// do stuff to create the values
return [
'key1' => 'value1',
'key2' => 'value2',
'fooKey1' => 'barValue1',
'fooKey2' => 'barValue2',
];
}
}
So now there's 4 values. These get passed to demo.phtml. However, the last 2 values are for the sub-partial, so we must call that. We even loop that, because we want to show them more than once!
<div class="row">
<div class="col-8 offset-2">
<table class="table table-striped table-bordered">
<tr>
<th><?= $this->translate('Key 1') ?></th>
<td><?= $this->escapeHtml($key1) // <-- Look, the key from Controller is now a variable! This is ZF magic :) ?></td>
</tr>
<tr>
<th><?= $this->translate('Key 2') ?></th>
<td><?= $this->escapeHtml($key2) ?></td>
</tr>
<?php for ($i = 0; $i < 3; $i++) : ?>
<?= $this->partial(
'custom/partial',
[
'value1' => $fooKey1, // <-- Look, the key from Controller is now a variable! This is ZF magic :)
'value2' => $fooKey2,
]
) ?>
<?php endfor ?>
</table>
</div>
</div>
Now, the above bit calls for the partial with name custom/partial. This must be registered. Example config below (place in module.config.php from your module):
'view_manager' => [
'template_map' => [
'custom/partial' => __DIR__ . '/../view/partials/demo-child.phtml',
// -- ^^ name -- ^^ location
],
'template_path_stack' => [
__DIR__ . '/../view',
],
],
File demo-child.phtml
<tr>
<th><?= $this->translate('Value 1') ?></th>
<td><?= $this->escapeHtml($value1) // <-- Look, from above partial - ZF magic :) ?></td>
</tr>
<tr>
<th><?= $this->translate('Value 2') ?></th>
<td><?= $this->escapeHtml($value2) ?></td>
</tr>

pass a keyvalue to my innerloop

In my view I want to show 2 recordsets, like this:
<?php
//var_dump(get_object_vars($projects));
foreach ($projects as $project) :
//var_dump(get_object_vars($project));
?>
<tr>
<td><?= $project['Projectname']?></td>
<td><?= $project['ProjectShortcut']?></td>
<td><?= $project['ProjectCiNumber']?></td>
<td><?= $project['Unitname']?></td>
<td><?= $project['UnitShortcut']?></td>
<td><?= $project['UnitCiNumber']?></td>
<td>
Edit
Delete
</td>
<?php foreach ($dcls as $dcl) : ?>
<td><?= $this->Path?></td>
<td><?= $this->UnitID?></td>
<td><?= $this->Importdate?></td>
</tr>
<?php endforeach;
endforeach; ?
How can I pass the keyvalue UnitID to the inner loop? I want to show all units, that works already and underneath the imports belonging to the unit.
Here also how I pass the data to the view from within my controller:
return new ViewModel([
'projects' => $this->projectTable->fetchAll(),
'dcls' => $this->table->fetchAll()
]);
somehow in the ViewModel or in the view I want to give a parameter UnitID to the dcl collection.
So my questions would be, where shall I do it, probably in my view? And how might be the exact syntax?

ZendFramework echo db values if first string = a?

I have this code at the moment to echo out all my database entries, I am wondering what it looks like in ZF to echo out the entries if the first value of the db entry is a.
Code:
<table>
<?php foreach($this->clubs as $clubs) : ?>
<tr>
<td><a href="<?php echo $this->url(array('controller' => 'club-description', 'action' => 'index', 'club_id' => $clubs->id));?>">
<?php echo $this->escape($clubs->club_name);?></a></td>
<td><?php echo $this->escape($clubs->rating);?></td>
</tr>
<?php endforeach; ?>
</table>
Thanks
Rik
So, based on your comment it sounds like you want to group the clubs by letter on the page. Assuming they are being ordered alphabetically in your database query, the simplest way to do this is to keep a variable which stores the first letter of the last club in the loop. Then, on each iteration, you compare the first letter of the current club with the first letter of the previous club. If they are different, you output a new heading.
With your code this would look something like this:
<?php
$previousLetter = false;
?>
<table>
<?php foreach($this->clubs as $clubs) : ?>
<?php
$firstLetter = substr($clubs->_club_name, 0, 1);
if ($firstLetter != $previousLetter) {
?>
<tr>
<td><?php echo $firstLetter; ?></td>
</tr>
<?php } ?>
<tr>
<td><a href="<?php echo $this->url(array('controller' => 'club-description', 'action' => 'index', 'club_id' => $clubs->id));?>">
<?php echo $this->escape($clubs->club_name);?></a></td>
<td><?php echo $this->escape($clubs->rating);?></td>
</tr>
<?php $previousLetter = $firstLetter; ?>
<?php endforeach; ?>
</table>

Trying to get property of non-object in Zend Framework 1.11 Application

I'm trying to create a table of information in a database query using Zend Framework 1.11, Zend_Db, and Zend_Db_Select.
Initially, I went about this by instantiating a new instance of my table and using $table->select().
However, when I went to JOIN it to another table, I got an error message that I wasn't able to JOIN using this select() method. After doing some research, I found that I had to call the select() method off of my default adapter if I wanted to do this JOIN. Seemed straightforward.
At this point, I have a model, a controller, and a view, but I think something is getting "lost in translation" between my Controller & my View.
Here is the model (inside Application_Model_DbTable_ActivityRequest):
public function getAllActivityRequests()
{
$db = $this->getDefaultAdapter();
$select = $db->select();
$select->from('activityrequest');
$select->where('isDeleted = ?','N');
$select->where('ReqType <> ?','Purchase Product');
$select->order('ReqTime DESC');
$query = $select->query();
$row = $query->fetchAll();
return $row;
}
And the Controller (Admin Controller):
public function getWorkAction()
{
$table = new Application_Model_DbTable_Activityrequest();
$row = $table->getAllActivityRequests();
$this->view->activityrequests = $row;
}
And (relevant part of)the View (admin/get-work):
<?php foreach($this->activityrequests as $activity): ?>
<tr>
<td><?= $activity->CustomerID; ?></td>
<td><?= $activity->ReqType; ?></td>
<td><?= $activity->ReqTime; ?></td>
<td><?= $activity->PickupTime; ?></td>
<td><?= $activity->AddressID; ?></td>
<td><?= $activity->Notes; ?></td>
<td><?= $activity->HeardAbtUs; ?></td>
<td><?= $activity->isDeleted; ?></td>
</tr>
<?php endforeach; ?>
When I do a var_dump of $row in both my model and my controller, I see the array that I'm trying to pass to the view. As soon as I get to the view, though, I get this error on a "non-object."
Any help would be appreciated.
Thanks!
You need to set your adapter / select / dbTable fetch mode.
See http://framework.zend.com/manual/en/zend.db.adapter.html#zend.db.adapter.select.fetch-mode
Alternatively, use the Zend_Db_Table to full advantage
public function getAllActivityRequests()
{
return $this->fetchAll(
$this->select()
->where('isDeleted = ?', 'N')
->where('ReqType <> ?', 'Purchase Product')
->order('ReqTime DESC')
);
}
See http://framework.zend.com/manual/en/zend.db.table.html#zend.db.table.fetch-all.select

zend paginator make other links and Action Calling concatinating with the URL

I am NEW to ZF .i used zend paginator in my first project .its working fine that is switching b/w pages with right result but the problem is that i have other links too in that view have a look to my view
<?php include "header.phtml"; ?>
<h1><?php echo $this->escape($this->title);?></h1>
<h2><?php echo $this->escape($this->description);?></h2>
Register
<table border="1" align="center">
<tr>
<th>User Name</th>
<th>First Name</th>
<th>Last Name</th>
<th>Action</th>
</tr>
<?php
foreach($this->paginator as $record){?>
<tr>
<td><?php echo $record->user_name;?></td>
<td><?php echo $record->first_name;?></td>
<td><?php echo $record->last_name;?></td>
<td>
Edit
|
Delete
</td>
</tr>
<?php } ?>
</table>
<?php echo $this->paginationControl($this->paginator, 'Sliding', 'pagination.phtml'); ?>
<?php include "footer.phtml"; ?>
as i said the pagination renders and working fine but when i click on these links
<a id="edit_link" href="edit/id/<?php echo $record->id;?>">Edit</a>
or
<a id="delete_link" href="del/id/<?php echo $record->id;?>">Delete</a>
or
Register
it is not calling the required action instead it make my url like this
(initial link) http://localhost/zend_login/web_root/index.php/task/list
after clicking any of the above link its like this
http://localhost/zend_login/web_root/index.php/task/list/page/edit/id/8
http://localhost/zend_login/web_root/index.php/task/list/page/edit/id/edit/id/23
http://localhost/zend_login/web_root/index.php/task/list/page/edit/id/edit/id/register http://localhost/zend_login/web_root/index.php/task/list/page/edit/id/edit/id/del/id/12
note its not happening when the page renders first time but when i click on any pagination link its doing so initialy its going to the reguired action and displaying a view...any help HERE IS THE ACTION
public function listAction(){
$registry = Zend_Registry::getInstance();
$DB = $registry['DB'];
$sql = "SELECT * FROM task ORDER BY task_name ASC";
$result = $DB->fetchAll($sql);
$page=$this->_getParam('page',1);
$paginator = Zend_Paginator::factory($result);
$paginator->setItemCountPerPage(3);
$paginator->setCurrentPageNumber($page);
$this->view->assign('title','Task List');
$this->view->assign('description','Below, are the Task:');
$this->view->paginator=$paginator;
}
Try:
// controller
$this->view->controllerName = $this->getRequest()->getControllerName();
// view script
Edit
|
Delete
or
Edit
|
Delete
Second example uses baseUrl() view helper that's using front controller's baseUrl setting. If you don't set baseUrl in your frontController it's trying to guess. As you're not using bootstrap functionality to set baseUrl you may do the following in index.php (not required):
$frontController = Zend_Controller_Front::getInstance();
$frontController->setBaseUrl('/');
Third possibility using url() view helper:
<a href="<?php echo $this->url(array(
'controller' => $controllerName,
'action' => 'edit',
'id' => $record_->id
)); ?>">Edit</a>
|
<a href="<?php echo $this->url(array(
'controller' => $controllerName,
'action' => 'del',
'id' => $record_->id
));?>">Delete</a>
add this in your action
$request = $this->getRequest();
$this->view->assign('url', $request->getBaseURL());
and replace your links in view with this
Add a Task
Edit
Delete