Respond as XML not working since cakePHP 3.1 - cakephp

I need to render an XML+XSL template in my application, and it used to work with cakePHP 3.0. I have made the switch to 3.1 recently and it has stopped working. The problem is that I was having a formatted view of my XML, while now I just get a plain string.
The migration guide says something about some changes in the RequestHandlerComponent, but nothing helpful (or maybe it's just me and I don't get the point :)).
This is my controller (it is exactly as it was with Cake3.0):
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Utility\Xml;
use Cake\Event\Event;
use Cake\Routing\Router;
use Cake\ORM\TableRegistry;
use Cake\Filesystem\Folder;
use Cake\Filesystem\File;
use Cake\Network\Email\Email;
use Cake\Core\Configure;
use Cake\I18n\Time;
/**
* Invoices Controller
*
* #property App\Model\Table\InvoicesTable $Invoices
*/
class InvoicesController extends AppController
{
public $components = [
'Browser',
'Reorder11'
];
public $helpers = [
'Multiple'
];
public $paginate = [];
public function initialize()
{
parent::initialize();
$this->loadComponent('Paginator');
$this->loadComponent('RequestHandler');
}
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->allow(['demo']);
}
/*
* ... several other functions ...
*/
public function viewxml($id = null)
{
$this->viewBuilder()->layout('xml');
$invoice = $this->Invoices->myInvoice($id, $this->Auth->user('id'));
$this->RequestHandler->respondAs('xml');
$this->set('invoice', $invoice);
}
}
The xml.ctp layout, which is really simple
echo $this->fetch('content');
and the viewxml.ctp template just echoes the xml as a string.
How can I obtain the formatted XML+XSL again?

Try add: $this->response->header(['Content-type' => 'application/xml']);
I had the same error but my output was pdf
working 3.0.14 using this code:
$this->RequestHandler->respondAs("pdf");
$this->layout = 'pdf/default';
$this->view = 'pdf/report1_pdf';
for 3.1.x (this works if u save the file and open later, if you try to open it directly on browser its print the plain file content as a txt/html):
$this->viewBuilder()->layout('pdf/default');
$this->viewBuilder()->template('pdf/report1_pdf');
$this->RequestHandler->respondAs('pdf');
$this->response->header(['Content-type' => 'application/pdf']);

Related

Cakephp 3 : How to insert data on db from a behavior

I've created a custom behavior on my CakePHP3 project and I would like to insert data on db from this behavior
Here is an clean exemple of my behavior, the function is well called and save of the form but the ADD Articles request doesn't work...
<?php
namespace App\Model\Behavior;
use Cake\ORM\Table;
use Cake\Event\Event;
use Cake\Core\Configure;
use Cake\I18n\I18n;
use Cake\ORM\Behavior;
use Cake\ORM\Entity;
use Cake\ORM\Query;
use Cake\ORM\TableRegistry;
use Cake\Utility\Inflector;
use App\Controller\AppController;
class HistorizeBehavior extends Behavior
{
public function beforeSave(Event $event, Entity $entity)
{
$this->historize($event, $entity);
}
public function historize(Event $event, Entity $entity) {
$articlesTable = TableRegistry::getTableLocator()->get('Articles');
$article = $articlesTable->newEntity();
$article->title = 'A New Article';
$article->body = 'This is the body of the article';
$articlesTable->save($article);
}
}
There is no error, no warning...but the data isn't saved..
Any idea why ?
Thanks

Cakephp3.0 I am calling Postcategories controller into Appcontroller and it is error " Call to undefined method Cake\Core\App::import() "

My Code tries to fetch all Main categories of the posts into Appcontroller to show on the homepage:
namespace App\Controller;
use Cake\Core\App;
use Cake\Controller\Controller;
class AppController extends Controller
{
public $helpers = ['Html', 'Form', 'Session','Time','Tree'];
public function initialize()
{
parent::initialize();
$this->loadComponent('Flash');
$this->maincategories();
}
function maincategories(){
App::import('Controller','Postcategories');
$postcates = new PostcategoriesController;
$postcates = $postcategory->find('threaded');
}
}
Your maincategories() method is wrong. You need the model, not the controller to retrieve the data from. You need to use TableRegistry::get('Postcategories') to get the Postcategories model and then call the find on that:-
public function maincategories()
{
$Postcategories = TableRegistry::get('Postcategories');
$this->set('postcategories', $Postcategories->find('threaded'));
}
$this->set() is setting the categories as a view variable ($postcategories). You will need to make sure you include use Cake\ORM\TableRegistry; at the top of your AppController file.
Make sure you've fully read the docs on retrieving data.

CakePHP 3 Custom helper not working

Hello i am trying to implement a helper extends the Html helper.
I created based on the documentation the below empty custom helper
<?php
namespace App\View\Helper;
use Cake\View\Helper;
use Cake\View\Helper\HtmlHelper;
use Cake\View\View;
/**
* MyHtml helper
*/
class MyHtmlHelper extends HtmlHelper
{
public function __construct(View $view, $config = []) {
parent::__construct($view, $config);
}
/**
* Default configuration.
*
* #var array
*/
protected $_defaultConfig = [];
}
I load both of them on AppController but when i use them on the view I receive the expected result from Html helper but not from custom helper why ? (the second helper doesn't return an error but just an empty result)
<?php echo $this->Html->tag('div','oti na einai2'); ?>
<?php echo $this->MyHtml->tag('div','oti na einai'); ?>
You broke it by overriding the parents default settings.
protected $_defaultConfig = [];
See the API documentation.
Merge whatever you need in the constructor for example instead of overriding the whole property with an empty array.

How cakephp2 call method another helper to current helper?

I have created helper name TicketHelper (has TicketsController), CommonHelper (no controller) and ExcelHelper (no controller). Inside TicketHelper it work fine when called any function of CommonHelper. Here example TicketHelper:
<?php
class TicketHelper extends AppHelper {
public $helpers = array('Session','Common');
public function myFunction(){
echo $this->Common->workfine();
}
?>
By the same action i called CommonHelper to ExcelHelper it produces error: Fatal error: Call to a member function workfine() on a non-object in
After many hours check, i found mistake problem with constructor
<?php
class TicketHelper extends AppHelper {
public $helpers = array('Session','Common');
public function myFunction(){
echo $this->Common->workfine();
}
//Here my problem constructor Note: function name and class name are the same
function TicketHelper (){
//My code here
}
/**
* It should be follow cakephp doc
* function __construct($id = false, $table = null, $ds = null) {
* parent::__construct($id, $table, $ds);
*
* }
*
*/
?>
You should not use a helper inside a controller. A helper is used for logic in the view. It is included in the controller but accessible in the view. For logic shared between controllers, use a component instead http://book.cakephp.org/2.0/en/controllers/components.html#creating-a-component.
If you still want to use a helper in the controller (not recommended):
$view = new View($this);
$myHelper = $view->loadHelper('MyHelper');

Define global variable for Models and Controllers at CakePHP 2.2

Currently i am using something like this:
//at bootstrap.php file
Configure::write('from', 'mymail#mydomain.com')
//at controllers or models files
$var = Configure::read('from')
The thing is, i would like to manage that variable through the database to be able to modify it in a simpler way.
I was thinking about doing it with AppModel but then it would only be accessible for Models and not controllers.
What should I do in this case?
Thanks.
You can create a separate model / plugin which will be mapped to a configuration table in your database. Then load it through $uses statement for controllers and App::import() for models.
class SystemSetting extends AppModel {
/**
* Return a list of all settings
*
* #access public
* #return array
*/
public function getSettings() {
return $this->find('all');
}
}
Then, in your controller:
class SomeController extends AppController {
var $uses = array('SystemSetting');
public function displaySettings() {
$settings = $this->SystemSetting->getSettings();
// .. your code
}
}
In model:
App::import('Model', 'SystemSettings.SystemSetting');
$settings = new SystemSetting();
$mySettings = $settings->getSettings();
This works just fine. Of course, you might also load settings in both AppController and AppModel to follow the DRY rule.
create the getSettings in your AppModel
in AppController you can write this method:
public function getSettings() {
return $this->{$this->modelClass}->getSettings();
}
this way the getSettings() method is available in any model and any controller
any model call:
$mysettings = $this->getSettings();
any controller call:
$mysettings = $this->MODELNAME->getSettings();

Resources