Calling MySQL functions in Lithium - php

How it's possible to call MySQL function (like GeomFromText() or SELECT AS) in the Lithium Framework's CRUD? Using database->read() is to inconvenient (I often change the database columns) and including the function in the variable's value only ends up being escaped.

Have you tried putting the function in the fields option?
For example, I do this:
Model::first(array(
'fields' => 'max(id)'
));
To clarify, in your query, try this (i have not tested this):
Model::first(array(
'fields' => array('field1 as myField', 'GeomFromText("POINT(x y)") as geom')
));

Related

JInput with parameter 'method' as <data-source> results in 'Fatal error: Call to a member function getString() on a non-object'

I'm quite new to Joomla! (and PHP in general) and trying to learn by developing a website on my local Joomla!-Installation.
I'm using WAMP-Server with PHP 5.5.12, Apache 2.4.9 and Joomla! 3.6.4.
Now I like to retrieve data from both $_POST and $_GET. Both are equaly insecure so it is only logical to retrieve and treat them together.
According to this article https://docs.joomla.org/Secure_coding_guidelines#Secure_strings i should be able to do it like this:
$string = JFactory::getApplication()->input->method->getString( 'myText', '' );
It's not working, complaining that 'method' is a non-object. ('Fatal error: Call to a member function getString() on a non-object')
All other data-source's from that same list (e.g. 'get', 'post', 'cookie', 'request', etc.) do not produce any error and seem to work flawless.
Unfortunately I need to retrieve data from either $_POST or $_GET (or both, but without $_COOKIE) wich is exactly what data-source='method' is supposed to do.
Of course I can use 'post' and 'get' sequentially but that seems stupid to me if there is an option wich could do it directly (less overhead? and slimmer code).
Than I maybe have to address priority, but let's leave that aside for now.
At https://docs.joomla.org/Retrieving_request_data_using_JInput the only Super-Global-'s mentioned are 'get', 'post' and 'server'. Not a word about the other sources that obviously
exist (no error occurring) or wich of the named sources is used as default.
My search has gone in circles for a while now and i can't find more related informations (targeting Joomla! or JInput, not PHP).
If I'm missing something fundamental here, feel free to tell me.
With this said my questions are now:
Is there any setting (or update) i have to make to get the 'method'-data-source working?
Is there another value (!='method') for data-source in JInput that can be used to directly retrieve data from exactly either $_POST
or $_GET or do I need to sequentially call 'post' and 'get' to accomplish this (maybe 'method' was renamed due to a conflict in names)?
Thanks for your time reading (and maybe answering).
I finally figured it out, thx to #Xorifelse for a push in the right direction.
The answers to my questions would be:
1) Is there any setting (or update) i have to make to get the 'method'- working?
One would have to add an array called '_METHOD' to the $GLOBALS-array in a way like this:
$GLOBALS['_METHOD'] = array_merge($_GET,$_POST);
Calling the JInput with data-source='method' then would return the merged content of $_GET and $_POST, with $_POST overwriting
values in $_GET if they have the same key.
2) Is there another value (!='method') for data-source in JInput that can be used...?
Every existing array inside the $GLOBALS-array (who's name starts with an underscore ('_') character and consists of uppercase characters only) can be used by calling the JInput with data-source beeing the name of that array (without the leading underscore).
If one has newly created and/or filled that array prior to the call by JInput doesn't matter. So using a name like _GETANDPOST instead of
_METHOD in the first question would describe its purpose mutch better.
BUT....
messing around with $GLOBALS is commonly considered bad practice!!
For everyone wondering how these values for the data-source in JInput work and why they seemingly could be called like a method
even they aren't methods:
the answer is to be found in 'magic methods' and 'property overloading'.
https://secure.php.net/manual/en/language.oop5.magic.php
https://secure.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members

Zend Framework: get POST parameters

We're using Zend Framework 1.12 and in several actions we have:
$postParams = $this->getAllParams();
...
$domainModel->update($postParams)
I was wondering if it's a good approach of handling params. Or is it better to define what parameters we want to get like:
$postParams = array(
'email' => $this->_getParam('email'),
'company' => $this->_getParam('company')
)
Or maybe use array intersection function to filter out unexpected parameters?
Best practice should be using
$postParams = array(
'email' => $this->_getParam('email'),
'company' => $this->_getParam('company')
);
Using array intersection may work (for checking the keys not values of course!)
Why is passing all params to $domainModel->update not so good?
Depends on logic of update but assuming that parameters are getting into database query, by manipulating http request i can inject some additional code or params into db query - maybe update the field you do not want to update by that particular action.
Downside of this approach is that when you change your model, you have to check your code for these params.
If all columns in table (including IDs) can be changed, you can use getAllParams. Except one problem: POST can contain variables that are not table columns, so you will get an error on update (column '...' not found).
Its not a good idea to pass all post parameters to model directly. Sometimes you may not want pass specific values to model.
Second, you may want to set some default values to the data in case its not provided in that case you can do $this->_getParam('company', DEFAULT_VALUE)
But i would say that usage of any method depends on your requirements and then you need to pick one which is most suitable for you.

One get method for each table field (model)

I have two models that have a relationship to each other. In one particular method I need to pick a field on the other, I usually create a method to pull just one field, if the field in the future subject to change, I will have to change only the return of function .. here are examples
I currently use the following: (this is just an example, obviously there is much more fields to get)
User model
function getUsername($user_id){
$this->id = $user_id;
return $this->field('my_username_field');
}
Server model
function getUserIdByServerId($server_id){
$this->id = $server_id;
return $this->field('my_user_id_field');
}
function getUsernameByServerId($server_id){
$user_id = $this->getUserIdByServerId($server_id);
return $this->User->getUsername($user_id);
}
This is a lot of code to write, because if I want to get more fields, I would have to write kind of one method for each field.. and if I do otherwise then when the field name change I'll have to re-write his name on all calls.. what is the better way?
Why do you want to fetch single fields? Especially if you need more than one? This doesnt make much sense. It is more effective to fetch the whole record (all fields, or select the 3-4 you need) and then deal with the data instead of doing multiple queries to the DB. That is inefficient and repetitive, not very DRY.
CakePHP already features a method for that, Model::field().
$this->Server->User->field('username', array(
'conditions' => array(
'User.server_id' => $serverId
)
));
But like I said, why are you not just doing this?
$this->Server->find('first', array(
'contain' => array(
'User'
),
'conditions' => array(
'User.server_id' => $serverId
)
));
You shouldn't need to create new methods in the models for this. What you would be doing now, I guess, in your Server Controller, would be something like this:
$this->Server->id = $server_id;
$username = $this->Server->getUsernameByServerId($this->Server->id);
What I think you can do, though, is just call something like this:
$this->Server->id = $server_id;
$username = $this->Server->User->field('username');
Or if you have (I think) PHP 5.4 or higher just use:
$this->Server->id = $server_id;
$username = $this->Server->read()['User']['username'];
(with PHP <5.4 you can just split that last line into two).
I don't think you should have to copy and paste loads of methods in the models for this.

Sandboxing Mongo->execute(MongoCode) in PHP to prevent any DB interaction

As a feature in the software I'm writing, I'm allowing myself to create calculators written in JS to compute the fees to be applied to a specific set of data, using said data as a reference. Since I'm using Mongo, I can run this safely server-side, and the browser can just call a php page and get the response. The function will be written from an administration control panel and saved to the database. I of course won't be doing any db interactions from inside that function, but executing mongocode is done within the database, so mongocode by nature can do db.foo
Just to protect myself and anyone else who might end up writing calculators, I've set db = null; in $context being passed to new MongoCode()
It looks a bit like this:
$sample = [
'estimatedvalue' => 200,
'estimatedcost' => 400,
'contractor' => false,
'db' => null,
];
$fees = [
'_id' => new MongoId(),
'name' => 'Friendly name!',
'code' => new MongoCode('function(){return (contractor ? estimatedCost : estimatedValue)*0.01; /* If a contractor is doing the work, base fee on cost. */}', $sample),
];
$a = $this->siteDB->execute($fees['code']);
if(isset($a['errno'])){
echo $a['errmsg'];
}else{
var_dump($a['retval']);
}
Fortunately, that works, and if I was to inject that into all context, there would be no db. commands runnable. I don't want to create a point where NoSQL injection can happen!
An example of something that this prevents is:
'code' => new MongoCode('function(){db.foo.remove();}', $sample),
// Since db is now null, the above won't work
My concern: Are there any other variables that exist in this MongoCode Execute environment that could be potentially harmful to leave in a user-editable function? I couldn't find any documentation on what else is accessible through mongocode functions. If db is it, then I'm all set!
This is not safe, and I don't think you can have a user-editable JS function that is. For example, this requires no variables and shuts down your server:
> db.eval("(new Mongo('localhost:27017')).getDB('admin').shutdownServer()")
They can insert data, drop databases, connect to other servers in your system, and generally wreck havoc.
If you are trying to allow a user-editable compute function in JavaScript, use a separate JS engine, pull the values from MongoDB, and pass the values + user-defined function to the totally separate JS engine.

Zend table html helper

Is there a Zend Helper to generate a Html Table using and array as input ?
partialLoop() is probably best if you need a lightweight, easily customizable table generator. If you want something a little more to take all but the business logic of report generation in Zend, take a look at zfdatagrid.
Most of all I use partialLoop() to generate tables. But sometimes, for simple data that don't require formatting, I use my simple view helper: https://gist.github.com/812481 .
Usage:
<?php echo $this->table()->setRows($rows); ?>
or...
<?php echo $this->table(null, $rows); ?>
The $rows can be associative array or any object that has toArray method (Zend_Db_Table_Rowset, Doctrine_Collection etc.). Following is more complicated example, with headers, caption, additional column:
echo $this->table()
->setCaption('List of something')
->setAttributes(array('class' => 'mytable', 'id' => 'currenciesList'))
->setColumns(array(
'currency' => 'Currency',
'rate' => 'Rate',
'edit_options' => '' // Custom column
))
// content for custom column.
->setCellContent(
'Delete', 'edit_options'
)
->setFooter('Something to write in footer...')
->setEmptyRowContent('Nothing found')
->setRows($rows);
But this approach is not as convenient as partialLoop, cause it takes input data and display it as is - it doesn't allow you to format values using Zend_Date, Zend_Currency or do custom cell formatting.
There is no native table zend view helper. However, you could use partialLoop view helper to ease generation of tables.
You can also use a PEAR's HTML_Table package. You can throw an array to the table class and it is gonna populate the table for you. It has some nice features like colouring odd and even lines, set parameters per row, per columns and per table body.
Find more info at http://pear.php.net/package/HTML_Table/docs/latest/HTML_Table/HTML_Table.html

Categories