I would get Joomla custom fields values from a PHP script. I include all necessary files and I can read checkbox values from "fields" table, the "fieldparams" column.
If I execute this code
$query = "select #__fields.fieldparams from #__fields where #__fields.id = 19";
$db->setQuery($query);
$result = $db->loadRowList();
foreach ($result as $value) {
echo gettype($value); // 01
echo $value[0]; // 02
$var = json_encode($value[0]);
echo gettype($var); // 03
}
the type of $value is "Array" (step 01), so if I access to $value[0] the result (step 02) is the global list (so I suppose this is an Array with 1 element)
{
"options":{
"options0":{"name":"type1","value":"1"},
"options1":{"name":"type2","value":"2"},
"options2":{"name":"type3","value":"3"},
"options3":{"name":"type4","value":"4"},
"options4":{"name":"type5","value":"5"}
}
}
but when I try to use json_encode the result (step 03) is a string.
In this way I can't access to keys and relative values.
What's wrong?
There are 2 issues here. 1. You're using ->loadRowList() which is a method designed to return an array of rows (i.e. multiple rows), not one as is implied by your where clause, and 2. Rather than using PHP's native functions, try using Joomla's JRegistry class instead.
To address these points:
1 Since you're only expecting 1 row to be returned (field with ID 19), replace your line:
$result = $db->loadRowList();
with
$result = $db->loadResult();
$result will contain the fieldparams column only.
2 Create an instance of the JRegistry class so we can access the key => value pairs:
// new registry
$registry = new JRegistry();
$registry->loadString($result); // load the string from the db
// if you need an array, use jregistry's toArray method
$arrayData = $registry->toArray();
Hope it helps,
Gez
Related
I have an array of the record retrieved from a SQL server database stored in an object $result. I will like to access each item in the array object and print it out to the screen. How can I achieve this? My attempt is below
$result = $DB->get_records_sql("SELECT rawname, ID FROM mdl_tag where tagType = 'institution'");
$result = array();
foreach ($result as $ $value) {
echo $value;
);
}
Here is the correct code:
// Get results from table 'tag', where 'tagtype' matches 'institution', with no sorting and returning fields 'id' and 'rawname'.
$results = $DB->get_records('tag', ['tagtype' => 'institution'], '', 'id, rawname');
foreach ($results as $value) {
echo $value->rawname;
}
So, there are a number of issues:
Use get_records, unless you really need to use get_records_sql.
If you do need to use get_records_sql, then the table is called {tag} not mdl_tag, otherwise you'll run into problems on any server that uses a prefix other than 'mdl_' (e.g. when running phpunit or behat tests).
Writing $result = array(); immediately before looping through the result will throw away the details from the database and replace them with an empty array
The results from get_records (or get_records_sql) are an array containing objects, each of which contains the values for the requested fields, so you need to access the individual value, not try to echo the entire object
All database fields in Moodle are lowercase, so 'tagtype' not 'tagType', 'id' not 'ID'.
I'm using PDO, and I managed to get the table columns despite the table name and create the bind variables, like in ... VALUES (:foo, :bar);.
The method I'm trying to do this is insert().
public function insert()
{
// the variable names depend on what table is being used at the moment the script runs.
// These methods use the PDO `getColumnMeta()` to retrieve the name of each column
$sql = "INSERT INTO {$this->getTableName()}({$this->getTableColumns()}) "
. "VALUES ({$this->getTableColumns(true)})";
// The previous method gets the name of each column and returns a single string, like "foo, bar, [...]"
// and this function is used to separate each word, with the specified delimiter
$col = explode(", ", $this->getTableColumns());
// Now here lays the problem.
// I already know how to retrieve the columns name as a variable, and
// how to dynamically create the get method, using `ucfirst()`
// What I need would be something like this being inside of a
// loop to retrieve all the separated words from `$col` array.
$data = array(
$col[$i] => "\$this->entity->get".ucfirst($col[$i])."()",
)
/*
* From now on, is what I need to do.
*/
// Lets pretend the column names are "foo, bar".
$data = array(
":foo" => $this->entity->getFoo(),
":bar" => $this->entity->getBar()
)
// That'd be the final array I need, and then continue with
$stm = $this->db->prepare($sql);
$stm->execute($data);
}
You have to loop over $data array and add function as per your requirement.
Fetch values from `... VALUES (:foo, :bar); Then explode as you did in your code , then loop over $col array and add values to $data as required
foreach($col as $val){
$method = "get".ucfirst( $val);
$data[ $val] = call_user_func(array( $this->entity,$method));
}
Above code may work as follow
$data[':foo'] = $this->entity->getFoo();
$data[':bar'] = $this->entity->getBar();
I have a MySQL query that will be converted to JSON and used in Obj C for each user with a specific id. I believe that this is a MySQL puzzle, but there may be an answer in JSON. I don't ask many questions, so I'll try to make it concise.
Here is a screen shot of values for one user. If you notice, the field_id may vary because not all info is required, so the id field will vary from 3 to 8 values for a given user_id:
I have to make a query where the results GROUP BY column1 (user_id), but only WHERE column2 (field_id) has the following values field_id='18' and field='19', Then (THE BIG PROBLEM) I need to populate the results in one GROUP with both values of column3 (value) so I can get results in one JSON object.
I already know how to convert to JSON for use in iOS, but I can only get it to give me results as two objects.
My current query
$query = "SELECT * FROM table1 WHERE field_id='18' OR field_id='19' ORDER BY user_id ";
Current Result
[{"id":"5","user_id":"461","field_id":"18","value":"1_MX4zNjcxNzM5Mn4x...","access":"0"},
{"id":"6","user_id":"461","field_id":"19","value":"T1==cGFydG5lcl9pZD0...","access":"0"},
{"id":"11","user_id":"463","field_id":"18","value":"1_MX4zNjcxNzM...","access":"0"},
{"id":"12","user_id":"463","field_id":"19","value":"T1==cGFydG5lcl9...","access":"0"}]
I need the two JSON objects with matching user_id fields as one object with results that differentiate field='18' value from field='19' value. Something like:
[{"id":"5","user_id":"461","field_id":"18","value18":"1_MX4zNjcxNzM5Mn4x...","value19":"T1==cGFydG5lcl9pZD0...","access":"0"},
{"id":"11","user_id":"463","field_id":"18","value18":"1_MX4zNjcxNzM...","value19":"T1==cGFydG5lcl9...","access":"0"}]
OR
[{"id":"5","user_id":"461","field_id='18'":"1_MX4zNjcxNzM5Mn4x...","field='19'":"T1==cGFydG5lcl9pZD0...","access":"0"},
{"id":"11","user_id":"463","field_id='18'":"1_MX4zNjcxNzM...","field='19'":"T1==cGFydG5lcl9...","access":"0"}]
THANKS...
I'm not 100% sure if this will work. I cannot easily try the JSON output of it. But what if you run a query like this?
SELECT id, user_id,
GROUP_CONCAT(field_id,':',value) field_id,
access
FROM table1 WHERE field_id='18' OR field_id='19'
GROUP BY user_id
ORDER BY user_id
You probably want to to look at handling this in PHP when reading in the result set.
So use your current query of
SELECT * FROM table1 WHERE field_id='18' OR field_id='19' ORDER BY user_id
But build result data object like this:
$results = array();
$i = -1;
$current_user_id = '';
while ($row = [YOUR MySQL FETCH MECHANISM HERE]) {
// determine if this record represents a new user id in the result set
// if so, we need to set up the user object and start another entry in top level array
if($current_user_id != $row['user_id']) {
// you have moved to a new user in the result set
// increment your array counter and set current user id
$i++; // will set value to 0 on first iteration
$current_user_id = $row['user_id'];
// build new array entry
$results[$i] = new stdClass();
$results[$i]->user_id = $current_user_id;
$results[$i]->fields = array();
}
// build field object for insertion
$field = new stdClass();
$field->field_id = $row['field_id'];
$field->value = $row['value'];
$results[$i]->fields[] = $field;
}
On encoding $results this would give you a JSON structure like this:
[
{
"user_id":"461",
"fields": [
{
"field_id":"18",
"value":"foobar"
},
{
"field_id":"19",
"value":"abcxyz"
}
]
},
...
]
This data structure is going to be more readily usable by consuming app than some solution which requires exploding concatenated field id/value strings. Also note that I have not included id field anywhere in data structure, as it has no meaning in this context. If you truly needed that id, you could add it as another property in the field object since that is where there is a one-to-one relationship (not with user_id).
Based on your comment, if the field value is known and you need to access it via field_id index, you can slightly modify what I have shown above to build index-able field listing rather than a simply array of objects:
$results = array();
$i = -1;
$current_user_id = '';
while ($row = [YOUR MySQL FETCH MECHANISM HERE]) {
// determine if this record represents a new user id in the result set
// if so, we need to set up the user object and start another entry in top level array
if($current_user_id != $row['user_id']) {
// you have moved to a new user in the result set
// increment your array counter and set current user id
$i++; // will set value to 0 on first iteration
$current_user_id = $row['user_id'];
// build new array entry
$results[$i] = new stdClass();
$results[$i]->user_id = $current_user_id;
$results[$i]->fields = array();
}
// insert field value at field_id index position
$results[$i]->fields[$row['field_id']] = $row['value'];
}
This would give you a JSON representation like this.
[
{
"user_id":"461",
"fields": {
"18":"foobar",
"19":"abcxyz"
}
},
...
]
This would allow easy look-up by client based on field id. Of course you may want to consider similar for user_id. From the user object you could just access fields->18 (or similar based on on client language syntax).
I have a situation where i have to programmatically do database inserts. I have multiple tables but the order of information of those tables are similar , i.e, in each table, the first coulmn in id, and second is a foregin key, and third is a name, and fourth is a blob and fifth is a text.
I searched php doc and found that I can use $objectName[index] to access the database property. I am getting error
Cannot use object of type stdClass as array in C:\....php on line .. .
The erroneous line is indicated on the code
private function uploadTemp($databaseObject, $table_name){
$this->load->database();
//get file_contents too;
$file_id = $databaseObject[3]; // < Here's where the error appeared
$this->db->from('tbl_file')->where('file_id',$file_id);
$q = $this->db->get();
$data = $q->row();
$query = "INSERT INTO $table_name VALUES(NULL, '".$databaseObject[2]."','".$data->filecontent."');";
$this->db->query($query);
}
I am using CodeIgniter as a framework.
Try casting to array:
$file_id = (array) $databaseObject[3];
As STDClass is just a dummy container with public dynamic variables and no methods, there should be no problems in casting it to array and backwards as well.
However in some situations numbers are used to represent a variable name.
Example:
$array ; //Is some array created by engines / database handlers.
$obj = (object) $array ;
echo $obj->0 ; //Hell it will not work.
echo $obj[0] ; //The same problem.
echo $obj->{'0'} ; //PERFECT
try this function get_object_vars()
or create function to convert to array
function array_to_object($array)//from CodeIgniter forum
{
return (is_array($array)) ? (object) array_map(__FUNCTION__, $array) : $array;
}
Scenario:
I am exporting a table Named "Registration" from access database and writing into a file named "isl.txt" in php using pdo. Fields separated by "," and Records separated by "\\"(i know it should be "\n" for convenience but it cant take a new line in text file. Don't know why !! so i have chosen "\\")
Registration Table in Access:
Roll_Num,Course,Marks,Discipline,Session
0,CS-101,89,CS,Fall94
0,CS-102,70,CS,Fall94
0,CS-103,59,CS,Fall94
Code:
$fl = fopen('isl.txt', 'w');
$db = new PDO("odbc:DRIVER={Microsoft Access Driver (*.mdb)};DBQ=D:\Islamabad.mdb;Uid=;Pwd=;");
$results = $db->query("select * from `Registration`");
while ($row = $results->fetch()) {
foreach ($row as $value) {
$lastv = end($row);
if ($value != $lastv){
fwrite($fl, $value.",");
}
}
fwrite($fl, $value."\\");
}
fclose($fl);
Output:
0,0,CS-101,CS-101,89,89,CS,CS,Fall94\0,0,CS-102,CS-102,70,70,CS,CS,Fall94\0,0,CS-103,CS-103,59,59,CS,CS,Fall94
Problem:
As u see, every single value of record is repeating two times. Please Check whats wrong with my code!!
The repeating values are because you are not specifying a fetch_style in $results->fetch([fetch_style]). According to the manual - http://php.net/manual/en/pdostatement.fetch.php - when fetch_style is not specified, it defaults to value of PDO::ATTR_DEFAULT_FETCH_MODE (which defaults to PDO::FETCH_BOTH).
PDO::FETCH_BOTH (default): returns an array indexed by both column
name and 0-indexed column number as returned in your result set
Try changing to -
while ($row = $results->fetch(PDO::FETCH_ASSOC)) {
OR
while ($row = $results->fetch(PDO::FETCH_NUM)) {