Add INSERT IGNORE Statement to CAKEPHP saveAll method - php

I need to add IGNORE option to saveAll() method in CAKEPHP. I want exact impementation of this . Some other SO questions answered related to validations and isUnique() checking like that. I need to implement this conditions , don't care waht is going on behind .
Please advise me.

The only way that I think this would be possible, other than using the execute() function provide by your data source is if you extended the Mysql datasource class and changed the behaviour of the create() and renderStatement() functions to includes case where you want it to append the IGNORE SQL keyword.
You'd want to place the data source file in APP/Model/Datasource/ and have it extends Mysql (assuming you use CakePHP 2+). Have a look at the 2 functions above. I'd just create a case where if uses 'createignore' instead of 'create' when calling renderStatement() when a certain option is passed to create().
That said, there most likely is a way to achieve what you're trying to do without going through that much trouble. If you elaborate on what you're trying to do, I might be able to give you a better answer.

Related

Modifying the SQL Eloquent uses per connection

I'm using the latest version of Laravel to connect to multiple data sources. One of those sources is an old Oracle database that contains a lot of white space thanks to some ancient software requiring string length. Despite this constraint, the fields have since been edited by new software with different requirements, and the columns are all varying length (and thus unknown).
On account of this, I need to edit the SQL that accesses it in order to wrap some pieces of the queries in trim()s. For instance,
$customer = Customer::whereRaw("RTRIM(\"ID\") = TO_CHAR($id)")->get();
I'd like to be able to merely call the find method:
$customer = Customer::find($id)
This is just one example. Pretty much all of the default functions are broken because the queries need some kind of trim prepended to them. I understand how I can affect the dynamic portion of the query, but I need to edit the column ahead of that. Sorry if this is a dumb question and I've just missed something in the documentation.
The easiest way to do this is to create a class that extends Eloquent, with the function for the query. Then modify all of your models to extend the new class instead of Eloquent. This way the models will have all the functionality of Eloquent as well as the functions you create.

To what extent is duplicate code OK in a model with CodeIgniter?

This is a long running question that gets me every time I am developing.
I suppose it is not specific to CodeIgniter, but as I am using it, I will consider it in my example.
Firstly, which is better:
function add_entry($data_array)
{
//code to add entry
}
function edit_entry($data_array)
{
//code to update entry
}
OR
function save_changes($what,$data_array)
{
//if what == update update
//otherwise insert
}
Both produce the same action, but does it really matter which one you use?
Getting onto more complicated things.
I have a page where I need to get ONE entry from the database.
I also have a page where I need to get all the entries from the same database ordered by a user specified column.
My resultant method is a function similar to
function($data_array,$order_by='',$limit='')
{
//get where $data_array
//if order_by!='' add order by
//if limit !='' add limit
}
As I develop my application and realise new places where I need 'similar' database functionality I am what feels like hacking previous methods so they work with all my case scenarios. The methods end up containing lots of conditional statements, and getting quite complex with in some cases 4 or 5 input parameters.
Have I missed the point? I don't want duplicate code, and when for the most part the functions are very similar I feel like this 'hacking' methodology works best.
Could someone advise?
Finally my admin functionality is part of the same application in an admin controller. I have an admin model which contains specific methods for admin db interaction. I however use some model functionality from 'user' models.
FOr example if on an admin page I need to get details of a db entry I may load the user model to access this function. There is nothing wrong/insecure about this..? right?
In addition to that within my admin model itself I need to get data about a user database entry so I call my user model directly from my admin model. This is strictly OK, but why? If i need data and there is already a method in my user model which gets it.. it seems a little pointless to rewrite the code in the admin model BUT each time that function is called does it load the whole user model again?
Thanks a lot all.
In order, add edit in the model vs save. Personally I have a save built in MY_Model that chooses whether it is a save or an edit depending on the existence of a primary key in the data being passed, so obviously I prefer that method it means a lot less duplication of code since I can use the save for any table without having functions in the model at all.
As to the second question I think it depends on situation. I also have a number of functions that have a ton of conditionals on them depending on where they're used and for what. In some cases I'm finding this makes the legibility of the code a little rough. If you're running them all through if statements it also could be impacting performance. DRY is a concept, not a rule and like other design concepts there are times when they just don't make sense, it's like database normalization, it's my personal opinion it's VERY easy to over normalize a database and destroy performance and usability.
Finally, using user functions in the admin code. I don't see an issue here at all, the reverse probably isn't true, but rewriting a function just because it's an "admin" function, when it's identical to a user function is utterly pointless. So you're correct there, it's a waste of time and space.

cakephp $uses or request action

i am in a situation where i need to fetch data from 6 models. i can't use associations as they are not related. So what should i use $uses or request action or any other solution
I'd recommend you to use
ClassRegistry::init("model_name")
or
loadModel("model_name")
instead.
E.g.
To use a User model
$this->User = ClassRegistry::init('User');
Or
$this->loadModel('User');
Then you can do some query like
$this->User->find("all");
If you are going to need those models for only one find call with associtaions needed, I recommend using bindModel, see Creating-and-Destroying-Associations-on-the-Fly.
I disagree with Travis. It is much better to use loadModel then you can be sure you're loading what you need when you need it. Who's to say you won't extend the model to include methods that don't require all those other models?
Cut and paste is a big boost to programmer performance.
You could try $uses, or, if you want to only load the models when and where you need them, you could use loadModel (http://book.cakephp.org/view/845/loadModel). LoadModel is better that $uses, performance wise.
As others recommended, you should use Controller::loadModel().
Additionaly, I'd suggest you make something like YourController::_loadMyMegaData() which would load all the necessary models and set your data. This will avoid loading those models by accident and spare you any if blocks later on.
Also, avoid requestAction() whenever possible, it's not only ugly, you also take a performance hit. (It has it's use of course, but that doesn't happen very often:))
You can use the following:
$this->loadModel('ModelName');
$this->ModelName->find();
If you are retrieving only single field than you can use virtual fields

How do you handle Zend_Paginator?

I was looking at Zend_Paginator in Zend Framework project using MVC, and it looks like an intersting tool.
It looks like we can give a select object as argument to the factory, it's interesting because it means that i should return a select object from my model, is it a good way to do ?
It seems to be a bit heavy to do this, since it won't be needed all the times...
I can also give an array, which could come as a result of my method model, but in the case where i have a lot of data, it could be complicated to retrieve all the data from my database each times.
How can i handle this ?
From the doc: http://framework.zend.com/manual/en/zend.paginator.usage.html
However, it is possible to directly supply a count or count query yourself. See the setRowCount() method in the DbSelect adapter for more information.
And
In the case of the Null adapter, in lieu of a data collection you must supply an item count to its constructor.
I would suggest doing the count yourself, and then manually setting it. That is, based upon the reading I just did. Also, the doc states that if you go the NULL route, you can provide an item-count (Integer) to the Paginator constructor instead - this seems a bit more reasonable than querying for the number with each request.
I have posted about this a few weeks ago. It is found here:
http://blog.ekini.net/2009/06/22/zend-framework-how-to-use-zend_paginator/
It is a pretty straight-forward tutorial. It starts with the form, then the controller, and goes down to the view and the paginator file.
Well, i finally found an interesting way to do.
First, i implemented a Domain Model pattern after a read on Matthew Weier O'Phinney's blog, who explains how to.
Then, i created my own adapter of Zend_Paginator, to agree with my Model.
It's the most interesting way to do, i've found until now.

Common CRUD functions in PHP

Is there a simple way to write a common function for each of the CRUD (create, retreive, update, delete) operations in PHP WITHOUT using any framework. For example I wish to have a single create function that takes the table name and field names as parameters and inserts data into a mySQL database. Another requirement is that the function should be able to support joins I.e. it should be able to insert data into multiple tables if required.
I know that these tasks could be done by using a framework but because of various reasons - too lengthy to explain here - I cannot use them.
If you try to write such function you'll soon discover that you've just realized yet another framework.
Of course not, that's why those frameworks exist and implement crud facilities. I'd first try to convince whomever it takes to actually use an existing framework and second, failing the above, I'd take a look at one or two of them and copy the implementation ideas. Failing all that you could take a look at http://www.phpobjectgenerator.com/
Without any frameworks includes without any ORMs? Otherwise I would suggest to have a look at Doctrine or Propel.
I know the way you feel.
Pork.DbObject is a simple class that you can extend your objects from. It just needs a db connection class to work.
please check out:
www.schizofreend.nl/pork.dbobject/
(oh yeah, yuk # php object generator. bloat alert! who wants to have those custom functions in every class???)
I came across this question on SO a while back and I ended up not finding anything at that time that did this in a light-weight fashion.
I ended up writing my own and I recently got around to open sourcing it (MIT license) in case others may find it useful. It's up on Github, feel free to check it out and use it if it fits your needs!
https://github.com/ArthurD/php-crud-model-class
Hopefully it will find some use - would love to see some improvements / contributions, too so feel free to submit pull requests! :-)
I wrote this very thing, it's kind of a polished scaffold. It's basically a class the constructor of which takes the table to be used, an array containing field names and types, and an action. Based on this action the object calls a method on itself. For example:
This is the array I pass:
$data = array(array('name' => 'id', 'type' => 'hidden')
, array('name' => 'student', 'type' => 'text', 'title' => 'Student'));
Then I call the constructor:
new MyScaffold($table, 'edit', $data, $_GET['id']);
In the above case the constructor calls the 'edit' method which presents a form displaying data from the $table, but only fields I set up in my array. The record it uses is determined by the $_GET method. In this example the 'student' field is presented as a text-box (hence the 'text' type). The 'title' is simply the label used. Being 'hidden' the ID field is not shown for editing but is available to the program for use.
If I had passed 'delete' instead of 'edit' it would delete the record from the GET variable. If I passed only a table name it would default to a list of records with buttons for edit, delete, and new.
It's just one class that contains all the CRUD with lots of customisability. You can make it as complicated or as simple as you wish. By making it a generic class I can drop it in to any project and just pass instructions, table information and configuration information. I might for one table not want to permit new records from being added through the scaffold, in this case I might set "newbutton" to be false in my parameters array.
It's not a framework in the conventional sense. Just a standalone class that handles everything internally. There are some drawbacks to this. The key ones must be that all my tables must have a primary key called 'id', you could get away without this but it would complicate matters. Another being that a large array detailing information about each table to be managed must be prepared, but you need only do this once.
For a tutorial on this idea see here
I think you should write your own functions that achieve CRUD unless you are stressed for time. it might be a framework on it's own but you need to learn what the framework does before screaming framework....it also becomes handy to know these things because you can easily pickup bugs on the framework and fix them your self........
it is possible but I wouldn't recommend it.
If there's absolutely NO way to use a framework you could create a base class that all other model objects extend. You can then make the base class generate & execute SQL based on get_class() and get_class_vars().
Is it possible? Yes.
Would I recommend it? nope

Categories