Using json encode - php

I am trying to use json encode for the first time and need some insight to what I am doing wrong.
It should look like this:
{ teams : [ ["2147483647", "9"],["2147483647", "6"],["2147483647", "4"],["11", "2147483647"],["5", "2147483647"],["12", "8"],["10", "3"],["2147483647", "7"], ], results : [ [ [[0, 1],[0, 1],[0, 1],[1, 0],[1, 0],[0, 0],[0, 0],[0, 1],], [[0, 0],[0, 0],[0, 0],[0, 0],], [[0, 0],[0, 0],], [[0, 0],[0, 0]] ] ] }
But the data being returned looks like this:-
{"teams":[["2147483647","10","5","12","11","2147483647","2147483647","2147483647"],["7","3","2147483647","8","2147483647","4","6","9"]],"results":[["0","0","0","0","0","0","0","0"],["0","0","0","0","0","0","0","0"]]}
Code:
public function getAutoCompleteData($tournID, $db)
{
$max = $this->max($tournID);
$one = $this->tourn_info("1on1", $tournID);
$total_matches = $max;
$after_matches = $max / 2;
$matches = $db->query($this->select("*", "matches", "leagueID='{$tournID}' AND league='tourn'"));
while ($row = $db->fetchAssoc($matches)) {
$clan1 = $this->getname($row['clan1'], $tournID, "tourn", $ac = NULL, 1, 1, $wc2 = 0);
$clan2 = $this->getname($row['clan2'], $tournID, "tourn", $ac = NULL, 1, 1, $wc2 = 1);
if ($row['matchno'] <= $after_matches) {
$clan_one[] = $row['clan1'];
$clan_two[] = $row['clan2'];
$score_one[] = $row['score1'];
$score_two[] = $row['score2'];
}
}
$data = array(
'teams' => array(
$clan_one,
$clan_two
),
'results' => array(
$score_one,
$score_two
)
);
return $data;
}
Where it shows teams, it should close the bracket ] every two teams?
Hope someone can help.

Not saying this will fix your problem, but it may help you to understand PHP.
class mustBeAClass{
protected function max($tnid){
// must have this function - can be public for outside method use
}
protected function tourn_info($typ, $tnid){
// must have this function - can be public for outside method use
}
protected function getname($arg0, $arg1, $arg2, $arg3, $arg4, $arg5, $arg6 = 0){
/* must have this function - can be public for outside method use
notice that $arg6 is how you assign default to arguments */
}
public function getAutoCompleteData($tournID, $db){
$db->open();
$max = $this->max($tournID); $one = $this->tourn_info("1on1", $tournID);
// what is the point of this ---->>>> $total_matches = $max;
$after_matches = $max / 2;
// notice query issue below
$matches = $db->query("SELECT * FROM matches WHERE leagueID ='$tournID' && league='tourn'"));
// while loop has problems
if($matches->num_rows < 1){
die('You have no matches');
}
else{
while($row = $db->fetch_assoc()){
$clan1 = $this->getname($row['clan1'], $tournID, 'tourn', null, 1, 1, 0);
$clan2 = $this->getname($row['clan2'], $tournID, 'tourn', null, 1, 1, 1);
if($row['matchno'] <= $after_matches) {
$clan_one[] = $row['clan1'];
$clan_two[] = $row['clan2'];
$score_one[] = $row['score1'];
$score_two[] = $row['score2'];
}
}
$data = array(
'teams' => array($clan_one, $clan_two),
'results' => array($score_one, $score_two)
);
}
$matches->free(); $db->close();
return $data;
}
}
$cls = new mustBeAClass;
echo json_encode($cls->getAutoCompleteData($tournId, $db));
Of course use the correct values for $tournId and your new mysqli(/*args*/) for $db.

Related

Updating multiple records in database using Codeigniter

Am trying to update multiple records in the database but my case I have a column total, which I want to update to different values. I haven't tried much here but hope I could get a clue on how to go about this.
My controller
public function update_record()
{
$id = ["19821", "19923", "19966", "19967"];
$total = ["8", "118", "90", "100"];
if ($this->some_model->batch_data('records', $total, $id) == true) {
echo "yes";
} else {
echo "no";
}
}
The Model
public function batch_data($table, $data, $where)
{
$this->db->where_in('id',$where);
$this->db->set('total',$data);
$this->db->update($table);
return true;
}
I have not tested this yet but currently looking for a more and efficient way of doing this.
If you still want to update multiple records using the update_batch method, you could first assign the id and total as key-value arrays, then use the update_batch method.
Controller :
public function update_record()
{
$id = ["19821", "19923", "19966", "19967"];
$total = ["8", "118", "90", "100"];
$update_data = [];
foreach ($id as $key => $value) {
$update_data[] = [
'id' => $value,
'total' => $total[$key]
];
}
if ($this->some_model->batch_data('records', $update_data) == true) {
echo "yes";
} else {
echo "no";
}
}
Model :
public function batch_data($table, $data)
{
$this->db->update_batch($table, $data, 'id'); // this will set the id column as the condition field
return true;
}
Output :
// preview query output :
// UPDATE `records`
// SET
// `total` =
// CASE
// WHEN `id` = '19821' THEN 8
// WHEN `id` = '19923' THEN 118
// WHEN `id` = '19966' THEN 90
// WHEN `id` = '19967' THEN 100
// ELSE `total`
// END
// WHERE `id` IN ('19821', '19923', '19966', '19967')
As per my comment. This is a method that combines the array in to key/value pairs and updates them 1x1 wrapped in a transaction (so if one query fails nothing changes).
This is the method I would personally use as I don't like update_batchs internal workings (cases).
$id = ["19821", "19923", "19966", "19967"];
$total = ["8", "118", "90", "100"];
$combined = array_combine($id, $total);
if (count($combined) > 0) {
$this->db->trans_start();
foreach ($combined as $id => $total) {
$this->db->set('total', $total);
$this->db->where('id', $id);
$this->db->update('sometable');
}
$this->db->trans_complete();
return $this->db->trans_status();
}
return true;
Try this, Only for single where condition
Controller:
public function update_record()
{
$tableName = "records";
$id = ["19821", "19923", "19966", "19967"];
$total = ["8", "118", "90", "100"];
$update_data = [];
foreach ($id as $key => $value) {
$update_data[] = [
'id' => $value,
'total' => $total[$key]
];
}
$whereKey = 'id';
$this->$this->some_model->batch_data($tableName, $updateData, $whereKey);
}
Model:
public function batch_data($tableName, $updateData, $whereKey)
{
$this->db->update_batch($tableName, $updateData, $whereKey);
}

Codeigniter Update Batch Error

I tried to find solutions
but i always get this error
You must specify an index to match on for batch updates.
public function editcompanionship()
{
$companionship_id = $this->input->post('companionship_id[]');
$missionary_one_id = $this->input->post('missionary_one_id[]');
$missionary_two_id = $this->input->post('missionary_two_id[]');
$missionary_three_id = $this->input->post('missionary_three_id[]');
$value_batch_update = array();
for($i=0; $i<count($companionship_id); $i++):
$value_batch_update[$i] = array(
'missionary_one_id' => $missionary_one_id[$i],
'missionary_two_id' => $missionary_two_id[$i],
'missionary_three_id' => $missionary_three_id[$i],
'modified' => date('Y-m-d H:i:s', time()),
);
endfor;
$this->db->where('companionship_id',$companionship_id[$i]);
$this->db->update_batch('pcdom_companionship',$value_batch_update);
$this->session->set_flashdata("success",alert("alert-success","Updated Successfully!"));
redirect(base_url('mrec/companionship'));
exit();
}
Can Any body knows?
The 3rd param of method update_batch() is required.
public function update_batch($table, $set = NULL, $index = NULL, $batch_size = 100)
{
....
if ($index === NULL)
{
return ($this->db_debug) ? $this->display_error('db_must_use_index') : FALSE;
}
...

How to filter based on I18n content with pagination component?

I have comeup with strange problem in cakephp 3.4. I am running filter query on i18n content like this.
if($this->request->query("q")){
$this->paginate["conditions"][$this->ContractTypes->translationField('title').' LIKE'] = '%'.$this->request->query("q").'%';
}
but following call is ending up in Database error
$records = $this->paginate($this->ContractTypes);
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'ContractTypes_title_translation.content' in 'where clause' SELECT (COUNT(*)) AS `count` FROM contract_types ContractTypes WHERE ContractTypes_title_translation.content like :c0
The paginator's count query is not joing i18n table. What is the best approach to solve this problem.
Thanks in advance,
I have solved this by creating my custom paginator component by editing the paginate function. My paginator contains following code incase somebody else is facing the same problem.
namespace Console\Controller\Component;
use Cake\Controller\Component\PaginatorComponent as BasePaginator;
class PaginatorComponent extends BasePaginator
{
public function paginate($object, array $settings = [])
{
$query = null;
if ($object instanceof QueryInterface) {
$query = $object;
$object = $query->repository();
}
$alias = $object->alias();
$options = $this->mergeOptions($alias, $settings);
$options = $this->validateSort($object, $options);
$options = $this->checkLimit($options);
$options += ['page' => 1, 'scope' => null];
$options['page'] = (int)$options['page'] < 1 ? 1 : (int)$options['page'];
list($finder, $options) = $this->_extractFinder($options);
if (empty($query)) {
$query = $object->find($finder, $options);
} else {
$query->applyOptions($options);
}
$cleanQuery = clone $query;
// My Modification Starts Here
$table = $cleanQuery->repository();
$results = $query->all();
$numResults = count($results);
$count = $numResults ? $cleanQuery->select([
"count"=>$cleanQuery
->func()
->count($table->alias().'.'.$table->primaryKey())
])->first()->count : 0;
// My Modification ends Here
$defaults = $this->getDefaults($alias, $settings);
unset($defaults[0]);
$page = $options['page'];
$limit = $options['limit'];
$pageCount = (int)ceil($count / $limit);
$requestedPage = $page;
$page = max(min($page, $pageCount), 1);
$request = $this->_registry->getController()->request;
$order = (array)$options['order'];
$sortDefault = $directionDefault = false;
if (!empty($defaults['order']) && count($defaults['order']) == 1) {
$sortDefault = key($defaults['order']);
$directionDefault = current($defaults['order']);
}
$paging = [
'finder' => $finder,
'page' => $page,
'current' => $numResults,
'count' => $count,
'perPage' => $limit,
'prevPage' => $page > 1,
'nextPage' => $count > ($page * $limit),
'pageCount' => $pageCount,
'sort' => key($order),
'direction' => current($order),
'limit' => $defaults['limit'] != $limit ? $limit : null,
'sortDefault' => $sortDefault,
'directionDefault' => $directionDefault,
'scope' => $options['scope'],
];
if (!$request->getParam('paging')) {
$request->params['paging'] = [];
}
$request->params['paging'] = [$alias => $paging] + (array)$request->getParam('paging');
if ($requestedPage > $page) {
throw new NotFoundException();
}
return $results;
}
}

Setting a variable to an operator then executing it

I'm new to PHP in general. I was messing with this code until I wanted to execute the function in one set instead of having to set and add, sub, div, mult function. How do I go about setting the variable operator with the two num sets?
Example pseudo code:
<?php
$Num1 = 10;
$Num2 = 5;
$operation = /;
$Sum = $Num1 $operation $Num2;
return $Sum;
Or something like:
<?php
// creating Class "Math"
class math {
//Executing the function
function exec($info = array()) {
return $info['num1'] $info['operation'] $info['num2'];
}
}
// Set info
$info = array(
'num1' => 10,
'num2' => 5,
'operation' => '/'
);
//execute the OOP
$math = new math;
echo $math->exec($info);
What you are asking for is referred to as the Strategy Pattern.
One way to do this is to define your functions
$multiply = function($operand0, $operand1) {
return $operand0*$operand1;
};
$add = function($operand0, $operand1) {
return $operand0+$operand1;
};
Then using your sample code:
class math {
//Executing the function
function exec($info = array()) {
return $info['operation']($info['num1'], $info['num2']);
}
}
// Set info
$info = array(
'num1' => 10,
'num2' => 5,
'operation' => $add
);
//execute the OOP
$math = new math;
echo $math->exec($info); //will print 15

PHP: how to return the right stuff

In my function I have more variables:
$disallowGallery = 1;
$disallowFriend = 1;
$disallowWall = 1;
$disallowPM = 1;
$disallowStatusComment = 1;
Now, i have a $check parameter. If it contains 'Gallery' the function should return the $disallowGallery variable. If it contains 'Friend' it should return the $disallowFriend variable.
I can do this myself with alot of if else statement / or an switch. But does there exist a more effective/simpler way?
The cleanest way to store this in my eyes would be an array:
$disallow = array(
"Gallery" => 1,
"Friend" => 1,
"Wall" => 1,
"PM" => 1,
"Comment" => 1
);
Inside a check function, you would do a check like so:
function check("Comment")
....
if (array_key_exists($area, $disallow))
return $disallow[$area];
else
return 0;
You can use variable variables:
function isDisallowed($type) {
$disallowGallery = 1;
$disallowFriend = 1;
$disallowWall = 1;
$disallowPM = 1;
$disallowStatusComment = 1;
$type = "disallowed$type";
return isset($$type) ? $$type : 1;
}
But I'd be more tempted to store your configuration in an associative array:
function isDisallowed($type) {
$disallowed = array (
'Gallery' => 1,
'Friend' => 1,
// ...
'StatusComment' => 1,
);
return array_key_exists($type, $disallowed) ? $disallowed[$type] : 1;
}
return ${'disallow' . $check};

Categories