General input/output error ? how to solve when the excel sheet? - php

Yii::import('application.extensions.phpexcel1.JPhpExcel');
$xls = new JPhpExcel('UTF-8', false, 'My Test Sheet');
$xls->addArray($sheet_generation);
$xls->generateXML('my-test');
In controller :
$get_user_info=$model->userInfo();
###### Sheet generation
$sheet_generation=$model->sheetInfo($get_user_info,$month,$year);
In model:-
public function sheetInfo($user_info,$sel_month,$sel_year)
{
$cnt=0;
foreach($user_info as $key => $line) {
$cnt=$cnt+1;
$linearr = $line;
//$linearr['heading']='';
//$linearr['imagess']='';
//array_push($linearr, "apple", "raspberry");
//print_r($linearr); exit;
$p=$line['Place'];
$place=Sheet::getWorkin($p);
$userid=$line['id'];
// Total present days
$no_days=Sheet::getPresent($userid,$sel_month,$sel_year);
$disti=$line['Designation'];
//designation names...............
$designation=Sheet::detDesignationName($disti);
/// Department name display..............
$d=$line['Department'];
$depart=Sheet:: getDepartmantName($d);
// Holiday
$holiday=Sheet::getHolidayDat($sel_month,$sel_year);
$approval=2;
$leave_count=Sheet::getLeaveCount($userid,$sel_month,$sel_year,$approval);
###### sunday leave count
$sunday=Sheet::sunday_count($sel_month,$sel_year);
########saturday count
$sat_count=Sheet::saturday_count($sel_month,$sel_year);
$sat_sunday_count=Sheet::weekday_count($userid,$sel_month,$sel_year);
//$heading="Attendance Report January 2014";
//$linearr['heading']=Yii::app()->theme->baseUrl/images/."favicon.ico";
//$linearr['Sno']=$cnt;
$linearr['Place']=$place;
$linearr['Designation'] =$designation;
$linearr['Department'] =$depart;
$sum_present=$sum_present+$no_days; // sum of present days....................
$linearr['present'] =$no_days;
$linearr['holiday'] =$holiday;
$linearr['leave'] =$leave_count;
$linearr['weekoffice'] =$sat_sunday_count;
$linearr['lop'] =0;
$resarr[] = $linearr;
}
//print_r($resarr); exit;
return $resarr;
}

Related

Chart JS + Laravel - How to add 0 to array

Employees and Projects
I have a pivot table where my code is grabbing all the projects that an employee is assigned to and the stage they are in.
Stages
Waiting
In Progress
Launched
This works and I get the chart to show the data if the employee has projects in each stage. However, when there are not projects in every stage, the array gets messed up and the bar graph shows the data but in the wrong part. For example:
Array that works: [2, 4, 2]
2 Waiting
4 In Progress
2 Launched
Array that doesn't work: [5]
0 Waiting
0 In Progress
5 Launched
In the second case, since the array only has one value, the 5 is shown under Waiting and not launched. How do I add 0's and get the array to show [0, 0, 5]?
Thanks.
$projects = Project::join('employee_project', 'projects.id', '=', 'employee_project.project_id')
->where('employee_project.employee_id', $id)
->groupBy('stage')
->select('stage', DB::raw('count(*) as total'))
->orderByRaw('case
when stage = "Waiting" then 1
when stage = "In Progress" then 2
when stage = "Launched" then 3
end')
->get();
foreach ($projects as $project) {
$t[] = $project->total;
}
$t = json_encode($t);
Updated Code
foreach ($projects as $project) {
if ($project->stage == 'Waiting') {
$t[0] = $project->total;
} elseif ($project->stage == 'In Progress') {
$t[1] = $project->total;
} elseif ($project->stage == 'Launched') {
$t[2] = $project->total;
} else {
$t[] = 0;
}
}
$t = json_encode($t);
This updated code gives me an associative array like {"1": 4, "2": 5}. ChartJS can't use the associative array. It needs an array like [0, 4, 5].
Also, the associative array doesn't include the 0's.
NEW UPDATE
foreach ($projects as $project) {
if($project->total > 0) {
$t[] = $project->total;
} else {
$t[] = 0;
}
}
This doesn't work either. Any ideas?
So I figured it out. I just had to add an array initializing it. Here is the code:
$t = [0,0,0];
foreach ($projects as $project) {
if($project->stage === 'Waiting') {
$t[0] = $project->total;
} elseif($project->stage === 'In Progress') {
$t[1] = $project->total;
} elseif($project->stage === 'Launched') {
$t[2] = $project->total;
} else {
$t[] = $t;
}
}
$t = json_encode($t);

How to correctly return and format an array of arrays in PHP

I'm using the Gmail API to list unread messages in my PHP application. I have a lot to learn and am cobbling together different bits of code I've found on here. Everything works, but it doesn't quite display the way I'd like. My code returns:
["
FedEx Shipment Notification
Mar 27th 2017 04:26 PM
TrackingUpdates#fedex.com","
Wellness 2 - Sp17: Re: Mike's fault!
Mar 26th 2017 06:13 PM
JohnSmith#mail.com "]
How can I change the code to return only:
FedEx Shipment Notification
Mar 27th 2017 04:26 PM
TrackingUpdates#fedex.com
Wellness 2 - Sp17: Re: Mike's fault!
Mar 26th 2017 06:13 PM
JohnSmith#mail.com
...without the extra quotation marks, square brackets, and commas between e-mails? I know I'm missing some basic knowledge.
I've tried
substr($inboxMessage, 2)
...in the list_messages function as a starting point to get rid of the first quotation mark and square bracket, but I got the error "substr() expects parameter 1 to be string, array given"
I also tried
$inboxMessages = array();
instead of
$inboxMessages = []
...but that returned only one e-mail and it was still in quotes and brackets.
I've also tried adding a json_decode in the get_content function:
$this->content->items[] = json_decode($getmail->obtain_gmail_feed());
...which produced the error "Array to string conversion in /var/www/moodle/lib/outputcomponents.php on line 1082"
I don't know what else to try, and I'd greatly appreciate some help.
Here's the code in lib.php:
class get_gmail {
function getHeader($headers, $name) {
foreach($headers as $header) {
if($header['name'] == $name) {
return $header['value'];
}
}
}
function listMessages($service, $userId) {
$list = $service->users_messages->listUsersMessages('me',
['maxResults' => 2, 'q' => 'in:inbox is:unread']);
$messageList = $list->getMessages();
$inboxMessage = [];
foreach($messageList as $mlist){
$optParamsGet2['format'] = 'full';
$single_message = $service->users_messages->get('me',$mlist->id,
$optParamsGet2);
$message_id = $mlist->id;
$headers = $single_message->getPayload()->getHeaders();
foreach($headers as $single) {
if ($single->getName() == 'Subject') {
$message_subject = '<p>'.$single->getValue().'<br />';
}
else if ($single->getName() == 'Date') {
$message_date = $single->getValue();
$message_date = date('M jS Y h:i A',
strtotime($message_date)).'<br />';
}
else if ($single->getName() == 'From') {
$message_sender = $single->getValue();
$message_sender = str_replace('"', '', $message_sender);
}
}
$inboxMessage[] =$message_subject.$message_date.$message_sender;
}
return $inboxMessage;
}
}
public function obtain_gmail_feed() {
global $CFG, $USER, $message_list;
require_once($CFG->libdir . '/google/lib.php');
session_start();
$client = new Google_Client();
$client->setAuthConfigFile($CFG-
>wwwroot.'/blocks/sko_gmail/client_secret.json');
$client->addScope(Google_Service_Gmail::MAIL_GOOGLE_COM);
$client->setAccessToken($_SESSION['access_token']);
$gmail_service = new Google_Service_Gmail($client);
$useremail = 'me';
$message_list = $this->listMessages($gmail_service, $useremail);
$message_list = json_encode($message_list);
return $message_list;
}
Then in index.php:
require_once($CFG->dirroot . '/blocks/sko_gmail/lib.php');
class block_sko_gmail extends block_list {
public function get_content() {
global $message_list;
$this->content = new stdClass;
$getmail = new get_gmail();
$this->content->items = array();
$this->content->items[] = $getmail->obtain_gmail_feed();
return $this->content;
}
}
I would also welcome any suggestions on how to improve my code.

PHP equivalent of Excel vlookup on array

After looking for a built in function in php I couldn't find a similar function to Excel's vlookup function.
I need a function that takes in an array and a lookup value and return the required info. So for example:
<?php
$baseCalculationPrice = [
0 => 50, //for values <=500 but >0
500 => 18, //for values <=3000 but >500
3000 => 15, //for values <=5000 but >3000
5000 => 14, //for values >5000
];
//Examples
$numPages = 499;
echo vlookup($numPages,$baseCalculationPrice); //should output 50
$numPages = 500;
echo vlookup($numPages,$baseCalculationPrice); //should output 50
$numPages = 501;
echo vlookup($numPages,$baseCalculationPrice); //should output 18
$numPages = 3000;
echo vlookup($numPages,$baseCalculationPrice); //should output 18
$numPages = 3001;
echo vlookup($numPages,$baseCalculationPrice); //should output 15
$numPages = 5000;
echo vlookup($numPages,$baseCalculationPrice); //should output 15
$numPages = 5001;
echo vlookup($numPages,$baseCalculationPrice); //should output 14
function vlookup($value,$array){
//magic code
return ....;
}
?>
I'm stuck even with the logic behind such a function, so any help would be great - thanks.
function vlookup($lookupValue,$array){
$result;
//test each set against the $lookupValue variable,
//and set/reset the $result value
foreach($array as $key => $value)
{
if($lookupValue > $key)
{
$result = $value;
}
}
return $result;
}
function testDeductionRate(){echo $this->deductionRate('ks',300);//zone and time are parameter for deductionRate() }
//deduction will be acted as vlookup (rangeLookup true)
function deductionRate($zone,$time){
$actualRate = 0;
$allRate = array(
'tg'=>array(0=>0,20=>200,30=>300,40=>400,50=>500),
'ks'=>array(0=>0,20=>100,30=>200,40=>300,50=>400),
'pc'=>array(0=>0,20=>50,30=>100,40=>200,50=>300)
);
if(isset($allRate[$zone])){
$rate = $allRate[$zone];
foreach($rate as $key=>$val){
if($time>=$key) $actualRate = $val;
}
}else{
return -1; //-1 means error
}
return $actualRate;
}
Try this if you would like to query on multi dimension associative array:
function vlookup($lookup_vakue, $lookup_array, $lookup_column, $result_column)
{
foreach ($lookup_array as $item) {
if ($item[$lookup_column] == $lookup_vakue) {
return $item[$result_column];
}
}
return false;
}
Sample Data
$data =
[
['id'=>1,'price'=>100],
['id'=>2,'price'=>200],
['id'=>3,'price'=>300]
];
Query Option
$result = vlookup('2',$data, 'id','price');
Result:
200
$getbase= function($amount) use ($baseCalculationPrice)
{
return (end(array_filter(
$baseCalculationPrice,function ($key) use ($amount)
{
return $key < $amount;
},
ARRAY_FILTER_USE_KEY
)));
};
amount 150 result 50
amount 1500 result 18
amount 25000 result 14

codeigniter mysql query output data display with specific condition

here are the following codes:
controller.php
function getchart() {
$prac = $this->input->post('prac_name');
$datee = $this->input->post('datee');
$this->load->model('appoint');
$results['appoint'] = $this->appoint->getappoint($prac , $datee);
$this->load->view('ajax/getappchart' , $results);
}
model.php
function getappoint($prac , $datee) {
$this->db->select('rdv.id as rdvid, startTime, endTime, day, firstname, lastname');
$this->db->from('rdv');
$this->db->join('contact', 'contact.id = rdv.contact_id');
$this->db->where('people_id',$practicien);
$this->db->where('DATE(day)', $datee);
$this->db->order_by('TIME(startTime)', 'ASC');
$query = $this->db->get();
//print_r($this->db->last_query());
return $query;
}
view.php
if ($appoint->num_rows() > 0) {
foreach($appoint->result() as $sub_row)
{
// display output.
}
} else {
echo 'No Appointments on Above Date.';
}
?>
what i need is, there are appointments with sametime and day(mostly 2 same).
if there is morethan 2, i need to set two different class style for both the appointment.
how can i achieve this ?
Thanks.
Final answer: done it with the help of #minhaz-ahmed
if ($appoint->num_rows() > 0) {
$appoint_counter = array();
foreach ($appoint->result() as $sub_row) {
//i am assuming your startTime is H:M:S, and day Y-M-D format
$key = strtotime($sub_row['day'] . ' ' . $sub_row['startTime']);
if (!isset($appoint_counter[$key])) {
$appoint_counter[$key] = 0;
}
$appoint_counter[$key] ++;
$style_class = 'YOUR_1ST_CLASS';
if ($appoint_counter[$key] > 2) {
$style_class = 'YOUR_2ND_CLASS';
}
//REST VIEW CODE
}
}
else {
echo 'No Appointments on Above Date.';
}
You can do like this
if ($appoint->num_rows() > 0) {
$appoint_counter = array();
foreach ($appoint->result() as $sub_row) {
//i am assuming your startTime is H:M:S, and day Y-M-D format
$key = strtotime($sub_row['day'] . ' ' . $sub_row['startTime']);
if (!isset($appoint_counter[$key])) {
$appoint_counter[$key] = 0;
}
$appoint_counter[$key] ++;
}
foreach ($appoint->result() as $sub_row) {
//i am assuming your startTime is H:M:S, and day Y-M-D format
$key = strtotime($sub_row['day'] . ' ' . $sub_row['startTime']);
$style_class = 'YOUR_1ST_CLASS';
if ($appoint_counter[$key] > 2) {
$style_class = 'YOUR_2ND_CLASS';
}
//YOUR REST VIEW
}
} else {
echo 'No Appointments on Above Date.';
}
What do you mean by class style? Anyway, the code below assumes you will put the results in a datagrid.
$prev_date = "";
$prev_time = "";
$results = $query->result();
foreach($results as $appointment) {
if ($prev_date != $appointment->day) // Assuming "day" is tables date
# Display output here
if ($prev_time != $appointment->startTime) // Logically, display should sort appointments by their starting time
# Display output here
# Display appointment rows here
$prev_date = $appointment->day;
$prev_time = $appointment->startTime;
}
if (empty($results)) {
# Display "no appointments found" output here
}

Looping class, for template engine kind of thing

I am updating my class Nesty so it's infinite but I'm having a little trouble.... Here is the class:
<?php
Class Nesty
{
// Class Variables
private $text;
private $data = array();
private $loops = 0;
private $maxLoops = 0;
public function __construct($text,$data = array(),$maxLoops = 5)
{
// Set the class vars
$this->text = $text;
$this->data = $data;
$this->maxLoops = $maxLoops;
}
// Loop function
private function loopThrough($data)
{
if( ($this->loops +1) > $this->maxLoops )
{
die("ERROR: Too many loops!");
}
else
{
$keys = array_keys($data);
for($x = 0; $x < count($keys); $x++)
{
if(is_array($data[$keys[$x]]))
{
$this->loopThrough($data[$keys[$x]]);
}
else
{
return $data[$keys[$x]];
}
}
}
}
// Templater method
public function template()
{
echo $this->loopThrough($this->data);
}
}
?>
Here is the code you would use to create an instance of the class:
<?php
// The nested array
$data = array(
"person" => array(
"name" => "Tom Arnfeld",
"age" => 15
),
"product" => array (
"name" => "Cakes",
"price" => array (
"single" => 59,
"double" => 99
)
),
"other" => "string"
);
// Retreive the template text
$file = "TestData.tpl";
$fp = fopen($file,"r");
$text = fread($fp,filesize($file));
// Create the Nesty object
require_once('Nesty.php');
$nesty = new Nesty($text,$data);
// Save the newly templated text to a variable $message
$message = $nesty->template();
// Print out $message on the page
echo("<pre>".$message."</pre>");
?>
Here is a sample template file:
Dear <!--[person][name]-->,
Thanks for contacting us regarding our <!--[product][name]-->. We will try and get back to you within the next 24 hours.
Please could you reply to this email to certify you will be charged $<!--[product][price][single]--> for the product.
Thanks,
Company.
The problem is that I only seem to get "string" out on the page... :(
Any ideas?
if(is_array($data[$keys[$x]]))
{
$this->loopThrough($data[$keys[$x]]);
}
else
{
return $data[$keys[$x]];
}
You need to return from the first if statement.
if(is_array($data[$keys[$x]]))
{
return $this->loopThrough($data[$keys[$x]]);
}
else
{
return $data[$keys[$x]];
}
This will get you a result back when you recurse. You're only getting "string" back right now because that key is only 1 level deep in your array structure.

Categories