Layout disappears for certain action in cake - layout

This was just working perfectly fine 5 minutes ago... I can't for the life of me figure out why this is happening. Basically, I start on a page, with a layout (== 'default'), no where in the controller code do I change the layout, in fact, no where in the application do I change the layout, but for some reason when I hit this certain action named 'addQuestion', it renders the view without a layout...
<?php
// medicalCasesController.php
public function addQuestion($caseId) {
if ($this->request->is('post')) {
$this->MedicalCase->Question->create();
if ($this->MedicalCase->Question->saveAll($this->request->data)) {
$this->request->data['Question']['id'] = $this->MedicalCase->Question->getLastInsertId();
$this->MedicalCase->Question->Image->processData($this->request->data);
$this->Session->setFlash(__('The question has been saved successfully.', true), 'flash/success');
$this->redirect(array('action' => 'addAnother', $caseId));
} else {
$this->Session->setFlash(__('There was a problem saving the question.', true), 'flash/failure');
}
}
$this->MedicalCase->id = $caseId;
$this->MedicalCase->contain(array('Question'));
$mc = $this->MedicalCase->read();
$count = $this->MedicalCase->getQuestions('count') + 1;
// mc, count, caseId
$this->set(compact('mc', 'count', 'caseId'));
}
?>
Keep in mind that I see the issue without POST data.. before the form is submitted. Let me know what else you need from me as I'm not quite sure how to diagnose/debug this issue.
Thanks
-Andrew

Figured it out, there was an error in a hidden divide.
Silly me..

Related

Child-view gets rendered twice

I've noticed that my child-view gets rendered twice for some reasons.
Here is a simple test-case:
Let's assume I've two controllers, ControllerA and ControllerB. I'm forwarding the action forwardTestAction from ControllerA to ControllerB and display the view returned from ControllerB as a child-view.
ControllerA::forwardTestAction()
public function forwardTestAction()
{
$childView = $this->forward()->dispatch(ControllerB::class, [
'action' => 'forward-test',
]);
$mainView = new ViewModel();
$mainView->addChild($childView, 'content');
return $mainView;
}
ControllerB::forwardTestAction()
public function forwardTestAction()
{
$number = new \stdClass();
$number->a = 10.4;
$view = new ViewModel([
'number' => $number,
]);
return $view;
}
Template forward-test.phtml of ControllerA
<?= $content; ?>
Template forward-test.phtml of ControllerB
<?php
$number->a = $this->currencyFormat($number->a);
echo $number->a;
The currencyFormat plugin throws an exception, because number gets formatted twice. The reason is because the child-view itself gets rendered twice.
That's a really weird behaviour and causes not only performance issues but also many other problems e.g. numberFormatting etc.
I'm doing something wrong?
Also I should mention that the html only gets outputted once, but the template gets rendered twice. Maybe it's just a weird constellation of my current setup. I also posted an issue on Github and they were not able to reproduce it.

Switch vs if else

I use if else for custom menus in Wordpress, to load various location menus based on parent page. The agency I work for is adding countless amounts of cities, and it's getting out of hand. One thing I am trying to do, is come up with a more efficient way to check the items, someone suggested switch, and I just wanted to throw this out there and see what you all think. These are not complete codes, and I know the menus are bad UX, and all that, it's not my call. I just want some input on performance differences. thanks.
Here is an example of switch code:
function is_subpage() {
global $post; // load details about this page
if ( is_page() && $post->post_parent ) { // test to see if the page has a parent
return $post->post_parent; // return the ID of the parent post
} else { // there is no parent so ...
return false; // ... the answer to the question is false
}
}
$selectedMenu = "primary";
$my_page_id = is_subpage();
if(!$my_page_id)
$my_page_id = get_the_ID();
switch ($my_page_id) {
case('489'):
$selectedMenu = 'columbus';
break;
case('6583'):
$selectedMenu = 'cumming';
break;
}
wp_nav_menu( array(
'theme_location' => 'main-menu',
'menu' => $selectedMenu,
'menu_class' => 'clearfix'
));
and here is an example of if else code:
if(is_page( '28' ) || '28' == $post->post_parent) { $locationMenu = 'louisville'; }
'menu' => $locationMenu,
Don't second guess or assume anything about the efficiency of an interpreter or compiler. if else might be better at one scenario and switch at another.
The problem with your code is readability and maintainability and not performance. It is hard to be specific without knowing all details about your needs, but it seems like what you need is to have at each post a custom field which indicates the menu associated with that post, and then the admin can configure them and you will have some more coffee time ;)
This is actually a worse solution in terms of performance, but if you really need the site to be fast then you are going to use a caching plugin which will make the whole php related performance discussion just a waste of time.
From a PHP perspective...
In lieu of having the page id to location table in a database, you could include a structure like this on pages you need it:
$idToLocation = array(
"489" => "columbus",
"6583" => "cumming"
// et cetera
);
Then to get the location:
$id = "489"; // for example
if (!array_key_exists($id, $idToLocation)) {
echo "location for id not found";
die();
}
$location = $idToLocation[$id];

Chunk is called with unique data, but renders duplicate content

Guess my problem is closely related to this one : Snippet duplicates content when used multiple times on page
The elements of my problem are the following ...
$modx->loadedResources : an (empty) array registered in the main $modx object via a snippet on page load. The array holds resource id's of the resources fetched from the DB randomly, so the same resource isn't shown twice on the same page.
loadRandomResource : a snippet using XPDO-style querying to load a random resource from the DB. It uses $modx->parseChunk() to fill the placeholders in the chunk with the resource data. With each call, it appends the id of the fetched resource being fetched to the $modx->loadResources array.
I used some debugging to check if the resource id's were properly being stored in my array, each time I fetch a new random resource, which happens to be the case. I then checked if the db returns different results, each time I call the loadRandomResource snippet, and it does. I can also confirm that it doesn't return duplicate results (I exclude the already loaded resource ID's in my XPDO query).
However, when calling the snippet at 3 various locations throughout my page template, all 3 snippet calls render the same resource, which is weird, since my debug shows that unique data is being loaded from the DB, and being sent to the chunk for rendering.
Please find below both the snippet code, as well as the chunk mark-up.
Does anyone have any ideas? Any help is much appreciated!
loadRandomResource snippet
$criteria = $modx->newQuery('modResource');
$criteria->select(array('id','pagetitle'));
$criteria->sortby('RAND()');
$criteria->limit(1);
$whereOptions = array(
'parent' => 2,
'deleted' => false,
'hidemenu' => false,
'published' => true
);
if (!empty($modx->loadedResources)) {
$whereOptions['id:NOT IN'] = $modx->loadedResources;
}
$criteria->where($whereOptions);
$resources = $modx->getCollection('modResource', $criteria);
$output = '';
foreach ($resources as $resource) {
$fields = $resource->toArray();
$fields['tv.tvPersonalPicture'] = $resource->getTVValue('tvPersonalPicture');
$fields['tv.tvJobTitle'] = $resource->getTVValue('tvJobTitle');
$output .= $modx->parseChunk('cnkTeamListItem', $fields);
$modx->loadedResources[] = $fields['id'];
}
return $output;
cnkTeamListItem chunk
<div>
<img src="[[+tv.tvPersonalPicture]]" alt="[[+pagetitle]]" />
<h2>[[+pagetitle]]<br /><span>[[+tv.tvJobTitle]]</span></h2>
</div>
I found the answer myself, solution is a bit odd though ...
I was calling my custom snippet 3 times in my template, uncached. Each call though exactly looked the same ...
[[!loadRandomResource? &type='teammember']]
Even though I had the exclamation mark in place, still ModX was caching the call, within the same page request.
So when I added a random unique value to each of the 3 calls, the issue was solved.
Call 1 : [[!loadRandomResource? &type='teammember' &unique='123465']]
Call 2 : [[!loadRandomResource? &type='teammember' &unique='987654']]
Call 1 : [[!loadRandomResource? &type='teammember' &unique='666666']]
Don't know if this is a bug or a feature, but I thought that the exclamation mark prevented caching, both across different pageviews, as well as within the same page view. Anyhow, thx for helping.
I use this code for rendering chunks in snippents:
<?php
// get chunk or template
$tplRow = $modx->getOption('tplRow', $scriptProperties, '');
// get template
if (substr($tplRow, 0, 6) == "#CODE:") {
$tplRow = substr($tplRow, 6);
} elseif ($chunk = $modx->getObject('modChunk', array('name' => $tplRow), true)) {
$tplRow = $chunk->getContent();
} else {
$tplRow = false;
}
// render template
$field = array(); // your fields
if ($tplRow) {
$chunk = $modx->newObject('modChunk');
$chunk->setCacheable(false);
$chunk->setContent($tplRow);
$output[]= $chunk->process($fields);
} else {
$output[]= '<pre>' . print_r($fields, 1) . '</pre>';
}
You do realize you could have done this with getResources, don't you?
http://rtfm.modx.com/display/ADDON/getResources
&sortby=`RAND()`&limit=`1`

Remove parent div if duplicate words

I'm using a service called Embedly to style my RSS feeds from Google Feedburner. I have an example code over her: JsFiddle
If you look closely you will see the source (CNN) at the end of every title. This is called .provider I would like to get rid of the whole div (.embed) IF the the word CNN is located elsewere (meaning duplicate) in the div, either .description or a
I tried many things, this is one of them really straight forward code:
$('.embed').each(function() {
if($('.embed a:first **could also be .description**', this).text() == $('.provider', this).text())
$(this).remove();
});
I cant figure out why its not working. I also used it with on and live click with no luck.
I just realized the 'embeds' are not there on document tready. I added a button with click event which you can click after the embedly has loaded in: http://jsfiddle.net/2VBSX/37/
You can use success event to filter provider class from the data like this :
EDITED
$('div.newscontainer').embedly({
key: ':3eccf441bf0f43acbb076da9817af27d',
success: function(oembed, dict) {
output = $(oembed['code']);
description = $(oembed['code']).find(".description").text();
var regex =new RegExp(output.find('.provider').text(),"i");
if(regex.exec(description) == null ) {
$(dict["node"]).parent().html(output);
}
output.find("a:eq(0)").text(); // First
output.find("a:eq(1)").text(); // Provider
}
});
Checkout this jsfiddle demo
Is it that what you want?
var regex = /CNN/;
$('.embed').each(function(index, element) {
if (regex.exec($('.embed a:first').text()) != null
&& regex.exec($('.provider').text()) != null) {
element.remove();
}
});

Paginator (Migration from Cake 1.3 to 2.0)

I am struggling with the paginator in Cakephp 2.0. While I am trying to migrate my application to 2.0 I cant find any solution to jump directly to the last page. In 1.3 it was quiet to do that from outside like this:
echo $this->Html->link(__('Flights'), array('controller' => 'flights',
'action' => 'index','page' => 'last'));
but this little trick putting 'page:last' in does not work anymore in 2.0. Of course there is a Paginator function called last, but this would only help if I would be already inside the app. My Problem is to access from an outside link directly the last page of the paginator.
This is the simple way:
echo $this->Paginator->last('Any text');
Other way to get the number of the last page is:
echo $this->Paginator->counter(array('format' => '{:pages}'));
Then you can use it to generate your link.
For more info:
http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::last
Shortly after creating a bounty for this question I found the solution to MY problem using CakePHP 2.2.4. I was trying to accomplish the same task but instead using version 2.2.4 instead instead of 2.0. Basically if I had a link that looked like http://www.domain.com/articles/page:last that the controller's pagination method would know what page to go to and display the correct results (articles) for that page. For example, if I have 110 articles and the pagination limit is set to 25, by going to that URL it would display page 5 of 5, showing records 101-110. I also wanted the same capability if I go to “page:first”.
I needed to change my library file lib/Cake/Controller/Component/PaginatorComponent.php.
I changed
if (intval($page) < 1) {
$page = 1;
}
To
if ((intval($page) < 1 && $page != "last") || $page == "first") {
$page = 1;
}
I also added
if($page == "last"){
$page = $pageCount;
}
After the line
$pageCount = intval(ceil($count / $limit));
Christian Waschke, with this solution, you can use the same link helper exactly how you wrote it in your question. For me, the link helper looked like this
<?php echo $this->Html->link('Go to Last Page', array('controller' => 'articles', 'action' => 'index', 'page' => 'last')); ?>
You can 'calculate' the last page yourself if 'last' is passed as the page number;
I would discourage making modifications in the CakePHP library files as this will make it hard to perform upgrades in the future.
Basically, the PaginatorHelper uses viewVars that are calculated and set by the PaginatorComponent, as seen here: https://github.com/cakephp/cakephp/blob/master/lib/Cake/Controller/Component/PaginatorComponent.php#L212
You can replicate this in your action; for example:
public function index()
{
if (!empty($this->request->params['named']['page'])) {
switch($this->request->params['named']['page']) {
case 'first':
// replace the 'last' with actual number of the first page
$this->request->params['named']['page'] = 1;
break;
case 'last':
// calculate the last page
$limit = 10; // your limit here
$count = $this->Flight->find('count');
$pageCount = intval(ceil($count / $limit));
// replace the 'last' with actual number of the last page
$this->request->params['named']['page'] = $pageCount;
break;
}
}
// then, paginate as usual
$this->set('data', $this->paginate('Flight'));
}
To improve this, this logic should be moved to a separate method, or to a behavior. However; as seen above, it is not required to make modifications in the PaginatorComponent!
Also note that the 'find(count)' in my example does not take additional conditions, they should be added if required
If you have a look in the CakePHP 1.3 source for paginate(), the code above is comparable; https://github.com/cakephp/cakephp/blob/1.3/cake/libs/controller/controller.php#L1204

Resources