I've got a CakePHP application that receives instant payment notifications from PayPal. I'd like to log the data that gets posted by PayPal. I could easily do that using something like this:
file_put_contents(LOGS . 'ipns.log', date('Y-m-d H:i:s ') . print_r($_POST, true) . "\n", FILE_APPEND|LOCK_EX);
But I prefer to do things "the CakePHP way™" whenever possible. I've already looked through the "Core Libraries > Logging" section of CakePHP's cookbook and am having trouble understanding it. I know it's not correct to do this:
CakeLog::write('ipns', print_r($_POST, true));
Although the above does seem to work, it can also cause problems, as shown here.
So what is the CakePHP way to do this? Or should I just use the raw PHP shown at the top of this question?
What you want is explained here http://book.cakephp.org/2.0/en/core-libraries/logging.html#creating-and-configuring-log-streams
But I would suggest you to read the whole page and not just this section.
I would write the ipn to a database table field by field and not into a file log. I can tell you this based on my experience with the paypal API. The advantages are obviously, you can for example lookup the ipns for an order, search for errors and so on.
According to Writing to log paragraph of Logging section of the 2.x cookbook:
CakeLog does not auto-configure itself anymore. As a result log files
will not be auto-created anymore if no stream is listening. Make sure
you got at least one default stream set up, if you want to listen to
all types and levels. Usually, you can just set the core FileLog class
to output into app/tmp/logs/:
CakeLog::config('default', array(
'engine' => 'File'
));
So, in order to make CakeLog::write('ipns', print_r($_POST, true)); to write to custom file app/tmp/logs/ipns.log you need in app/Config/bootstrap.php instead of:
/**
* Configures default file logging options
*/
App::uses('CakeLog', 'Log');
CakeLog::config('debug', array(
'engine' => 'File',
'types' => array('notice', 'info', 'debug'),
'file' => 'debug',
));
CakeLog::config('error', array(
'engine' => 'File',
'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
'file' => 'error',
));
write:
/**
* Configures default file logging options
*/
App::uses('CakeLog', 'Log');
CakeLog::config('default', array(
'engine' => 'File'
));
Related
I am using the 'MeioUpload' plugin found here 'https://github.com/jrbasso/MeioUpload' and Cakephp 2.x.
Currently using this for single image uploads, please can anyone give advice on how to handle multiple image uploads using this plugin. Currently the db table storing the images holds filename, dir, mimetype and filesize fields for each image. I want to store more than one image for each of my posts when adding a new post. Any help would be much appreciated, thanks in advance :).
As I mentioned in my comment, you might want to try https://github.com/josegonzalez/upload as MeioUpload is now deprecated, and it's developer is working on that new upload plugin I linked to.
Either way, the following info for MeioUpload holds true for the new plugin, too.
MeioUpload is built to handle one uploaded file per corresponding set of fields. I don't think the example in MeioUpload's ReadMe is ideal, as it seems to imply that you have to have a table of 'images', where as in reality, you can have a table of just about anything, where each record holds one or more uploaded files (be it images, PDF's, MP3's... anything).
So, with that in mind, you have two solutions:
1) If your posts will have a potentially infinite number of images (ie, not a fixed, small number) then you can have Posts and Images in separate tables, and set up a hasMany relationship between them. See http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html
2) If you know that each post will only have a max of say 3 or 4 (or some other relatively small number) of images, then you can implement 3 (or 4, or X) sets of image fields in your Posts table / model, each to handle a separate upload. They'd be named, eg. featured_image_filename, feautred_image_dir, etc; image2_filename, image2_dir, image2_mimetype, etc; image3_filename, image3_dir, etc.
Your acts as would look something like:
var $actsAs = array(
'MeioUpload.MeioUpload' => array(
'featured_image_filename' => array(
'fields' => array(
'dir' => 'featured_image_dir',
'filesize' => 'featured_image_filesize',
'mimetype' => 'featured_image_mimetype'
),
),
'image2_filename' => array(
'fields' => array(
'dir' => 'image2_dir',
'filesize' => 'image2_filesize',
'mimetype' => 'image2_mimetype'
),
),
'image3_filename' => array(
'fields' => array(
'dir' => 'image3_dir',
'filesize' => 'image3_filesize',
'mimetype' => 'image3_mimetype'
),
),
)
);
This second solution is hardly ideal database design, but sometimes when you know there'll never be more than a few images, it's just the easiest way to do it - both in terms of developing, and in terms of an easy to use UI.
Make sense?
I run my CakePHP project on localhost. When I fill form, after clicking submit button it shows the following error:
Missing Datasource Configuration
Error: The datasource configuration Array was not found in
database.php.
I actually configured a datasource it and it looks like:
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Postgres',
'persistent' => false,
'host' => 'localhost',
'login' => 'arwinder',
'password' => 'root',
'database' => 'sh_db',
'prefix' => '',
//'encoding' => 'utf8',
);
public $test = array(
'datasource' => 'Database/Postgres',
'persistent' => false,
'host' => 'localhost',
'login' => 'arwinder',
'password' => 'root',
'database' => 'sh_db',
'prefix' => '',
//'encoding' => 'utf8',
);
}
... but it's getting ignored.
I had a similar issue when trying to work with data sanitation (it's a weird use case, what can I say).
The documentation for sanitize::escape says,
"The name of the database to quote the string for, as named in your
app/Config/database.php file."
It does not, in fact, take the name of the database eg. 'mydatabase' nor does it accept the host eg. 'localhost', nor does it accept the 'datasource' eg. 'Database/Mysql'. When given any of these VALUES, you get the error mentioned in the question.
What you actually need is the name of the "Datasource" to use. Again, the documentation for 'Datasource' fails to answer this topic.
I was stumped. So I searched for that error and found this unanswered post.
I finally found a solution thorough shear dumb luck, and as this post is still the highest result for this error on Google, I came back to answer it.
What you actually need is the variable name (key not value) as listed in the above mentioned config file. eg. $default or $test or $what_have_you. You then provide 'default', 'test' or 'what_have_you' depending on hostname.
Here's what boggles my mind the most. If the Datasource changes from 'production' to 'testing' and also 'local_dev' knowing which one is in use at any given time is critical to making Sanitise:escape() work.
But hold on a second... if you're doing that, you basically set the datasource to $default using a constructor method as documented here on SO so in all actuality, this mysterious 'Datasource' it's almost always going to be 'default' unless it's set on the fly, as an override, in your model which would be known while you're Sanitizing for a manual query anyway.
In fact, the default for this parameter is indeed, 'default'. It's not a required parameter at all, but because the documentation doesn't list it as optional or provide a defined default parameter (on that particular page) one might assume that it is required.
Anyway, the answer is to not provide a $datasource unless you are using $useDBConfig to specify a different datasource in your Model already.
I found this similar question but my problem is different.
I moved my CakePHP 2.2 application to another server. There exists no problem before migration. Most of the things works fine after migration. I can reach most of my database tables etc. But when I try to reach one of my table I get this error:
"Error 500: Table stats for model Stat was not found in datasource default."
To solve this, I checked this folder:
"/app/tmp/cache/models"
In that folder there is a file for each of my tables
myapp_cake_model_default_mydatabase_table1
myapp_cake_model_default_mydatabase_table2
myapp_cake_model_default_mydatabase_table3
etc..
But there is no file for stats table. Can it be the problem? Or how can I solve this?
(Permission for "/app/tmp/cache/models" folder is 755)
In Database.php I have this:
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'myuser',
'password' => 'mypass',
'database' => 'mydatabase',
'prefix' => '',
'encoding' => 'utf8',
);
Edit:
As I noted in thaJeztah's answer's comments, after removing all files inside app/tmp/cache/persistent problem solved. CakePHP created new model cache files and it worked. After one year I found out the real problem. The problem was setting cake model files' clear duration. I set clearing cache to +999 days, so model files aren't regenerated. While making model changes you can set lower values for model cache clear:
Cache::config('_cake_model_', array(
'engine' => "File",
'prefix' => "myapp_". 'cake_model_',
'path' => CACHE . 'models' . DS,
'serialize' => ($engine === 'File'),
'duration' => "+999 days"
));
Have you checked your database, e.g. in phpMyAdmin or MySql workbench? Does the table exist in the database?
The error message indicates that the table could not be accessed using the default connection. It's possible that the table is really missing, or that the user you're using to connect to the database does not have the right permissions for that table.
If you migrated the database from another server, did you get error messages while importing? If you did not create a dump enclosed in a transaction, it's possible that the database dump was only partially imported.
[update] this suggestion solved the problem;
Remove all files from app/tmp/cache/persistent and /app/tmp/cache/models then enable debugging. Your SQL log/debug should show the queries that CakePhp is using to detect if the tables exist in the database. Also you'll be able to check if Cake writes to the tmp files without problems
If this is helpfull for anyone in 2020.
I had this problem even with full permissions to the model. I tried doing like #theJeztah suggested which was clearing cache/persistent but the problem persisted. What ended up working was switching Configure::write('debug', 0) to Configure::write('debug', 2) in the app/core file. Presumably on debug it clears the cache better.
I'm new to cakePHP, so I may be missing the obvious.
The system is running the latest download using Microsoft SQL Server 2005 as database. I appreciate that is slightly unusual, but having fixed the URL rewrite I have seen no other issues.
I'd like use a custom finderQuery, but I cannot even seem to replace the default. Specifically if I use
var $hasMany = array(
'RecyclateTypeConversion' => array(
'className' => 'RecyclateTypeConversion',
'foreignKey' => 'recyclate_type_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => 'select RecyclateTypeConversion.* from recyclate_type_conversions AS RecyclateTypeConversion WHERE RecyclateTypeConversion.recyclate_type_id IN ({$__cakeID__$});',
'counterQuery' => ''
),
};
I see this error
Notice (8): Undefined index:
RecyclateTypeConversion
[CORE\cake\libs\model\datasources\dbo_source.php,
line 1099]
However the SQL debug output confirms that the query itself runs fine and returns 4 records, and the view runs perfectly when the finderQuery is not specified. I've tried for other hasMany tables too - with exactly the same issue.
I've attempted to replace the select all with specific field selects but I still see the same result. Certainly the query looks correct according to the manual - so what is the issue (and could it be related to using MSSQL?)
EDIT: Also, as this hasn't picked up any answers yet, what would be the best approach to debugging this? I've started hunting through the cake debugging class, but so far with no results that have enlightened me. Of course if there is a problem I'll be submitting the fix back to the project.
Have you checked that there is actually a model called RecyclateTypeConversion and that it exists with a filename according to the CakePHP conventions? I.e. is there a models/recyclate_type_conversion.php and in that file, is the name of the model defined as RecyclateTypeConversion.
The error that you're getting seems to hint that there's something wrong with that model name, as it cannot find the associated index.
Try removing the alias from the select - the casting in in the "AS RecyclateTypeConversion" part should handle that for you. I also like to wrap custom queries in double quotes. I might just be paranoid but string parsing errors have bit me in the ass before.
var $hasMany = array(
'RecyclateTypeConversion' => array(
'className' => 'RecyclateTypeConversion',
'foreignKey' => 'recyclate_type_id',
'dependent' => false,
'finderQuery' => "select * from recyclate_type_conversions AS RecyclateTypeConversion WHERE RecyclateTypeConversion.recyclate_type_id IN ({$__cakeID__$});",
);
Also, I highly suggest you use the DebugKit plugin and post back to us the query log and a debug output of the find results that cause the errors.
did you go through it step by step?
try to get everything (all data)
try conditions
try "containable" behavior to create your query, which makes things a lot easier in my opinion
Have you tried CakePHP Debug Kit
I would like to use the MeioUpload Behavior for uploading any kind of documents(I want every extension to be accepted). I've already seen this question , but it didn't work for me, for some strange reason I can only upload image and pdf files for the other types of files I get this error when I attempt to submit the form : "The post could not be saved. Please, try again."
Edit: Well, it looks like I was finally able to upload other kind of files apart from images,I had to write the options 'allowedMime' and 'allowedExt' in camelCase (in the documentation they use the underscore version 'allowed_mime', 'allowed_ext' I don't know why:( ), but I haven't been able to upload .zip files and most importantly I still don't know how to tell the behaviour to accept anything
var $actsAs = array(
'MeioUpload' => array(
'link_referencia' => array(
'dir' => 'files{DS}uploads',
'create_directory' => true,
'allowedMime' => array('application/pdf', 'application/msword', 'application/vnd.ms-powerpoint', 'application/vnd.ms-excel', 'application/rtf', 'application/zip'),
'allowedExt' => array('.pdf', '.doc', '.ppt', '.xls', '.rtf', '.zip'),
'default' => false,
)
)
);
Thanks in advance
It can be use for anything, hence it's called meioUpload and not meioImage
Just set the allowed file extensions and mime types when you initialiave the behavior.
Step 4 has an example http://www.meiocodigo.com/projects/meioupload/