Log database updates with CakePHP - cakephp

How to log all database updates, inserts or deletes in CakePHP made using pure SQL?
example:
$this->Car->query('update cars set color = "red" ');

Extend whatever datasource you're using and override the _execute()
method to log and pass back to the parent.
For example, let's assume you're currently using dbo_mysql. That means
your db config is something like this:
class DATABASE_CONFIG {
var $default = array(
'driver' => 'mysql',
// ...
)
}
so change 'driver' to 'mysql_with_log', and create the file app/model/
datasources/dbo/mysql_with_log.php :
<?php
require (LIBS . 'model' . DS . 'datasources' . DS . 'dbo' . DS .'dbo_mysql.php');
class DboMysqlWithLog extends DboMysql {
function _execute($sql) {
$this->log($sql);
return parent::_execute($sql);
}
}
?>
Here is the Reference link.
You can also use Cake debug kit.
This plugin will also help you to save SQL Logs. Here is the link to download Debug Kit.

Related

Mocking a function using Laravel and PHPUnit

I am using Laravel for some projects, and I am trying to create a test for a function. Here is the function in the my controller:
public function showThoseThings()
{
return parent::httpRequest(
function ($context) {
$context->results['item'] = $this->object->findOrFail(list_id)->getElements;
}
);
}
the "getElements()" function is defined in the model as follow:
public function getElements()
{
return $this->belongsToMany(
'things',
'thing_to_list',
'list_id',
'thing_id'
)
->withPivot('position')
->orderBy('thing_to_list.position');
}
Basically in the backend there are three tables a list table that is a collection of things, then there is a things table that contains multiple things associated to a list then we have the pivot table. How can I mock this with Laravel. Here is what I have been doing:
public function testShowThoseTHingsSuccess()
{
$this->mock->shouldReceive('findOrFail')->with(1)->andReturn($this->mock);
$this->mock->shouldReceive('getElements')->once()->andReturn($this->mock);
$response = $this->call('GET', 'workingURI');
var_dump($response);
$this->assertTrue($response->isOk());
But when running phpunit in the command line I am getting:
"Unknown Error","message":"SQLSTATE[HY000] [1045] Access denied for user... Fails asserting that false is true".
I don't know what your $this->mock->.. method is doing but apparently not mocking the model you want.
Because the error states that something tries to access the database and doesn't have correct credentials.
Also the lines:
$this->mock->shouldReceive('findOrFail')->with(1)->andReturn($this->mock);
$this->mock->shouldReceive('getElements')->once()->andReturn($this->mock);
Makes no sense to me, You create a mock of a model and when the methods findOrFail or getElements are triggered you return the same object.. The method getElements states to me that there should be returned some array with models..
Some more info when you want to use a testing database
When you run unit test with laravel and uses the base test class, then Laravel sets the environment to testing. Make sure that you have the right database configuration set for this environment.
You can use I.E. the following configuration to create a database in memory for testing:
// app/config/testing/database.php
<?php
return array(
'default' => 'sqlite',
'connections' => array(
'sqlite' => array(
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => ''
),
)
);
Don't forget to migrate your DB schema before testing, place the following line in the public function setUp() of the base test class.
Artisan::call('migrate');
More info about simulating the databse: NetTuts testing laravel models

Using CakePdf data not showing

I am in a problem with CakePDF. I am using CakePHP 2.3.6. I setup everything alright, bootstrap & core files are ok.
Now, I want to generate many pdf files and download them. Downloading is ok, but when I download the files, I see that the generated pdf files say that Undefined $data, where I send $data to the view file.
Here is my Controller code:
App::uses('CakePdf', 'CakePdf.pdf');
// ...
public function createPdf($id) {
$data = $this->DBTable->find('all', array(
'conditions' => array(
'DBTable.id' => $id
)
));
$CakePdf = new CakePdf();
$path = APP . DS . 'pdf' . DS;
foreach($data as $key => $var) {
$CakePdf->template('create', 'default');
$this->set('var', $var);
$this->pdfConfig = array(
'orientation' => 'portrait',
'filename' => $var['id'] . ".pdf"
);
$CakePdf->write($path . $var['id'] . ".pdf");
}
}
Here, I am downloading the files some other way, not related to this problem, because downloading is ok. When I run this, all files are downloaded, and when I see the files, they say "Udefined var", looks like they didn't receive and variable called "$var".
I put the view file & the layout exactly where ceeram said.
What should I do now ? Please help me.
At last I got a solution to this. In the Controller function :
$data=$this->ModelName->find('all');
$CakePdf=new CakePdf();
$CakePdf->template('view_file','default');
$this->pdfConfig=array('orientation'=>'portrait','filename'=>$data['name']);
$CakePdf->viewVars(array('data'=>$data));
$CakePdf->write($path.$data['name'].".pdf");
Here, we have to store view_file.ctp in View/Pdf/, and default in View/Layouts/pdf/, where view_file.ctp is the view file which we want to convert in pdf, and default is the layout for this specific view file.
Here, viewVars() function passes the data to the view file, just like :
$this->set->('data',$data);
Let me know if anything is not clear here.
Thanks.

Cakephp: Print a comment after queries in Sql log

I'm using CakePHP 2.3 with the debug kit plugin and I need print a commentary after each Sql query in my logs. Is it possible modify it?
To solve the problem, I created an instance of Mysql in Model/Datasource called DboCustomSource. Here I have overwritten the function execute of DboSource to modify the variable $sql.
App::uses('Mysql', 'Model/Datasource/Database');
class DboCustomSource extends Mysql{
public function execute($sql, $options = array(), $params = array()){
$sql .= 'comment';
return parent::execute($sql, $options, $params);
}
}
It's necessary to modify datasource in database's configuration: 'datasource' => 'DboCustomSource'.

CakePHP 2 : Implement CakePDF plugin by Ceeram

I'm trying to implement the CakePDF plugin designed by Ceeram.
I'm using CakePHP 2 and I work locally using wamp on windows vista. I followed everything from the readme file but I got stucked at some point.
What I'd firstly like to do is converting an HTML link to a PDF using the WkHtmlToPdf engine. I see many people having issues to make it work so I'm gonna detail all the way through in the following different steps.
STEP 1: CakePdf plugin by Ceeram
I downloaded the plugin at https://github.com/ceeram/CakePdf
I extracted the contained folder into app/Plugin/CakePdf
STEP 2: Bootstrap
I added the following lines - app/Config/bootstrap.php :
CakePlugin::load('CakePdf', array('bootstrap' => true, 'routes' => true));
Configure::write('CakePdf', array(
'engine' => 'CakePdf.WkHtmlToPdf'
),
'orientation' => 'portrait',
'download' => true
));
STEP 3: Controller
I've created my controller "InvoicesController.php" - app/Controller/InvoicesController.php:
class InvoicesController extends AppController {
public $components = array('RequestHandler');
public function view($id = null) {
$this->Invoice->id = $id;
if (!$this->Invoice->exists()) {
throw new NotFoundException(__('Invalid invoice'));
}
$this->pdfConfig = array(
'orientation' => 'portrait',
'filename' => 'Invoice_' . $id
);
$this->set('invoice', $this->Invoice->read(null, $id));
}
}
STEP 4: View
I've created a pdf folder in my view folder and created view.ctp in app/View/Invoices/pdf/view.ctp.
STEP 5: Layout
I've created a pdf folder in my layout folder and created app/View/Layouts/pdf/default.ctp
That's about it. In my view I couldn't make a PDF file from an URL.
Although I have to mention I'm new in OOP and CakePHP so I would be very grateful if you could show me how to have this done. I'm sure it will help others because there many newbies like me who want to do this but because it's all meant for advanced programmers we cannot figure out how to put the pieces together.
Thank you very much for your understanding and your help!
[THIS POST IS MODIFIED EACH TIME THERE IS A NEW ANSWER WHICH IMPROVES IT]
You need to add RequestHandler component, and browse to localhost/invoices/view/1.pdf
Looks like i had forgotten to mention to add RequestHandler component in the readme.
Also for WkHtmlToPdf you need to tell it where it can find it, and since you are on windows the default location surely wont work for you. You can set the location with Configure::write('CakePdf.binary', 'C:\Program Files\wkhtmltopdf\wkhtmltopdf.exe') after having installed it on windows
You are missing this code in app/config/routers.php
Router::parseExtensions();
Router::setExtensions(array('json', 'xml', 'rss', 'pdf'));
details available on:
http://www.dereuromark.de/2014/04/08/generating-pdfs-with-cakephp/

CakePHP generate and save PDF

I am using CakePHP for an application that does auto generation of vouchers to a PDF file. But they work through user clicks. Now I wish to create it automatically and have the file written to the server hard disk. Then later on, these files will get zipped up and sent to an email of my choice.
For the PDFs I use Html2ps/Html2pdf component found in CakePHP. You can view it here http://bakery.cakephp.org/articles/Casmo/2010/06/26/creating-pdf-files-with-html2ps-html2pdf
One issue I have is the formatting doesn't look right. If I have links that look like this:
http://www.mydomain.com/this-is-my-perma-link
They will render this way in the generated PDF:
http://www.mydomain.com/this- is- my- perma- link
And that would be a broken link. I've tried to use other characters to replace the dash but it doesn't work. I am not sure why.
Another issue is, how can I write the generated PDF file to my server hard disk? Is there an option for me to do that and how do I define the destination. Any examples?
Maybe thanks in advance!
Hi you can to use FPDF library . and you can to save file in the server and then redirect to other function.
check the next code.
///Call to library
<?php
App::uses('AppController', 'Controller');
require_once APP . 'Vendor' . DS . 'fpdf17' . DS . 'fpdf.php';
class TestController extends AppController {
public function test(){
--Create fpdf.
$pdf = new FPDF();
$pdf->AddPage();
$pdf->Output('files/Report.pdf');
$pdf->text($x,$y,'Txt');
return $this->redirect(
array('controller' => 'Test', 'action' => 'test_new')
);
}
}

Resources