I'm building an analytics tool for some Facebook pages where I can view page information and statistics.
The problem is that it takes a long time to load the data using FQL, almost 50 seconds to load the page fully. The problem is that it needs to request a query for each day when I want to know all the new likes within a month and then count them all up.
These are the functions I'm using:
function getmetrics($objectid, $metrics, $end_time, $period){
global $facebook;
$fql = "SELECT value FROM insights WHERE object_id=$objectid AND metric='$metrics' AND end_time=end_time_date('$end_time') AND period=$period";
$response = $facebook->api(array(
'method' => 'fql.query',
'query' =>$fql,
));
if (!empty($response)){
return $response[0]['value'];
}
else{
return "no results found";
}
}
function getdailymetrics($objectid, $metrics, $end_time , $days ){
global $facebook;
$total = 0;
do {
$amount = getmetrics($objectid, $metrics, $end_time, '86400');
$total += $amount;
$pieces = explode("-", $end_time);
$end_time = date("Y-m-d", mktime(0, 0, 0, date($pieces[1]),date($pieces[2])-1,date($pieces[0])));
$days--;
} while($days > 1);
return $total;
}
On the front end:
<table>
<tr>
<td>Total likes</td>
<?php
$like1 = getmetrics($samsung, 'page_fans', '2012-01-29', '0');
$like2 = getmetrics($samsung, 'page_fans', '2012-02-26', '0');
$likep = round((($like2/$like1)-1)*100, 2);
?>
<td><?php echo $like1; ?></td>
<td><?php echo $likep; ?>%</td>
<td><?php echo $like2; ?></td>
</tr>
<tr>
<td>New Likes</td>
<?php
$newlikes1 = getdailymetrics($samsung, 'page_fan_adds', '2012-01-29', '28');
$newlikes2 = getdailymetrics($samsung, 'page_fan_adds', '2012-02-26', '28');
$newlikep = round((($newlikes2/$newlikes1)-1)*100, 2);
?>
<td><?php echo $newlikes1; ?></td>
<td><?php echo $newlikep; ?>%</td>
<td><?php echo $newlikes2; ?></td>
</tr>
<tr>
<td>Daily New Likes</td>
<td><?php echo round($newlikes1/28); ?></td>
<td><?php echo $newlikep; ?>%</td>
<td><?php echo round($newlikes2/28); ?></td>
</tr>
</table>
Is there a way to speed this up or is there a more efficient way?
You can try to reduce the amount of requests in two ways. First, you can use batch requests to send up to 50 queries to FB in one request. Also you can try to change your query, so that it would request insights for several days at once, like end_time in (values_list).
Also you could do some caching of the results.
And, though it depends on your certain case, maybe you could consider pulling insights with daemon (if you have the objects to pull data for), and storing it in the database.
I resolved the problem with a different method of fetching the data, using this function:
function getfromuntil($objectid, $metric, $start_time, $end_time){
global $facebook;
try {
$start_time = $timestamp = strtotime($start_time);
$end_time = $timestamp = strtotime($end_time);
$response = $facebook->api('/'.$objectid.'/insights/'.$metric.'?since='.$start_time.'&until='.$end_time);
} catch (FacebookApiException $e){
error_log($e);
}
$total = 0;
foreach ($response['data'][0]['values'] as $value) {
$total += $value['value'];
}
return $total;
}
Related
I have a table that store the data of ID, ID Login, Name, etc. But i just want to show the data based on ID Login
Here My Controller :
function index(){
$data['hasil'] = $this->M_user_lapor->index_model();
$this->load->view('v_user_lapor/index', $data);
}
My Model :
function index_model(){
$baca = $this->db->query('select * from user_lapor');
if($baca->num_rows() > 0){
foreach ($baca->result() as $data){
$hasil[] = array(
'id_login'=>$data->id_login,
'id_lapor'=>$data->id_lapor,
'nm_unit'=>$data->nm_unit,
'pic_1'=>$data->pic_1,
'pic_2'=>$data->pic_2,
'ip_wan'=>$data->ip_wan,
'ip_lan'=>$data->ip_lan,
'prov'=>$data->prov,
'icn_sid'=>$data->icn_sid,
'tlkm_sid'=>$data->tlkm_sid,
'status'=>$data->status,
);
}
return json_encode ($hasil);
}else{
return false;
}
}
View :
<tbody>
<?php
if ($hasil){
$no = 1;
$array = json_decode($hasil, true);
foreach($array as $data) {
?>
<tr>
<td class="text-center"><?php echo $no++;?></td>
<td><?php echo $data['nm_unit'];?></td>
<td><?php echo $data['pic_1'];?></td>
<td><?php echo $data['pic_2'];?></td>
<td><?php echo $data['ip_wan'];?></td>
<td><?php echo $data['ip_lan'];?></td>
<td><?php echo $data['prov'];?></td>
<td><?php echo $data['icn_sid'];?></td>
<td><?php echo $data['tlkm_sid'];?></td>
</tr>
<?php
}
}
?>
</tbody>
As you can see, there is id_login inside my model, and i want to show the table data based on it, hopefully somebody can help me because i'm just using the codeigniter, thnaks
I solved this by myself, lol. I just pass the id_login value from session, so i add this to my controller :
function index(){
$id_login = $this->session->id_login;
$data['hasil'] = $this->M_user_lapor->index_model($id_login);
$this->load->view('v_user_lapor/index', $data);
}
And call it to my model :
function index_model($id_login){
$baca = $this->db->query('select * from user_lapor where id_login='.$id_login);
if($baca->num_rows() > 0){
foreach ($baca->result() as $data){
$hasil[] = array(
'id_login'=>$data->id_login,
'id_lapor'=>$data->id_lapor,
'nm_unit'=>$data->nm_unit,
'pic_1'=>$data->pic_1,
'pic_2'=>$data->pic_2,
'ip_wan'=>$data->ip_wan,
'ip_lan'=>$data->ip_lan,
'prov'=>$data->prov,
'icn_sid'=>$data->icn_sid,
'tlkm_sid'=>$data->tlkm_sid,
'status'=>$data->status,
);
}
return json_encode ($hasil);
}else{
return false;
}
}
I need help, have managed to get here with searching Google.. but stuck and cannot find a decent sample to complete my script.
A simple stock value system for intranet.
All i need is to calculate the Stock Value Row.
See red block on Image below
My Code - How do I calculate the Value with my script.. or any other example's I can look (links here or on the web) - MANY THANKS....
<?php try {
$conn = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb);
$conn->exec("SET CHARACTER SET utf8");// Sets encoding UTF-8
$sql = "select * from stock_dry where stock_cat_id = 14 order by stock_id" ;
$result = $conn->query($sql);
if($result !== false) {
$cols = $result->columnCount();
foreach($result as $row) {
?>
<tr>
<td class="text-left"><?php echo $row['stock_id'];?></td>
<td class="text-left"><?php echo $row['stock_name'];?></td>
<td class="text-left"><?php echo $row['stock_count'];?></td>
<td class="text-left"><?php echo $row['stock_price'];?></td>
<td class="text-left">
<?php
$sum_total = $row['stock_count'] * $row['stock_price'];
echo $sum_total;
?>
</td>
<td class="text-left"><?php echo $row['stock_cat'];?></td>
</tr>
<?php
} } $conn = null; }
catch(PDOException $e) {
echo $e->getMessage();}
?>
You can simply add a variable before the loop like:
$tot = 0;
Then after the sum_total calc you add:
$tot += $sum_total;
I also would do a little change to sum_total (if you work with integers):
$sum_total = intval( $row['stock_count'] ) * intval( $row['stock_price'] );
or (if you work with floats):
$sum_total = floatval( $row['stock_count'] ) * floatval( $row['stock_price'] );
And with:
echo number_format( $sum_total, 2 );
You can print the float with 2 decimals.
I want to validate and insert multiple records from single form.
I tried following solution, but it is not validating each records.
Yii - multiple records in one form submission
I've used something like this in my form:
<td><?php echo CHtml::activeTextField($item,"[$i]name"); ?></td>
<td><?php echo CHtml::activeTextField($item,"[$i]price"); ?></td>
<td><?php echo CHtml::activeTextField($item,"[$i]count"); ?></td>
<td><?php echo CHtml::activeTextArea($item,"[$i]description"); ?></td>
And in my controller I've done similar to this:
public function actionBatchCreate() {
$models=array();
// since you know how many models
$i=0;
while($i<5) {
$models[]=Modelname::model();
// you can also allocate memory for the model with `new Modelname` instead
// of assigning the static model
}
if (isset($_POST['Modelname'])) {
$valid=true;
foreach ($_POST['Modelname'] as $j=>$model) {
if (isset($_POST['Modelname'][$j])) {
$models[$j]=new Modelname; // if you had static model only
$models[$j]->attributes=$model;
$valid=$models[$j]->validate() && $valid;
}
}
if ($valid) {
$i=0;
while (isset($models[$i])) {
$models[$i++]->save(false);// models have already been validated
}
// anything else that you want to do, for example a redirect to admin page
$this->redirect(array('modelname/admin'));
}
}
$this->render('batch-create-form',array('models'=>$models));
}
<?php
public function actionBatchCreate()
{
$arrItems = array();
$valid = true;
if(isset($_POST['Modelname'])) {
foreach ($_POST['Modelname'] as $i => $notUsed)
{
$objItem = new Modelname();
$objItem->attributes=$_POST['Modelname'][$i];
$valid = $objItem->validate() && $valid;
$arrItems[] = $objItem;
}
if($valid) {
foreach ($arrItems as $objItemValidated) {
$objItemValidated->save();
}
$this->redirect(array('modelname/admin'));
}
}
// optional create a initial empty row in View
if(!count($arrItems)) {
$arrItems[] = new Modelname();
}
$this->render('batch-create-form',array('models'=>$arrItems));
}
View-File batch-create-form.php
<table>
<?php foreach($models AS $i => $item):?>
<tr>
<td><?php echo CHtml::activeTextField($item,"[$i]name"); ?></td>
<td><?php echo CHtml::activeTextField($item,"[$i]price"); ?></td>
<td><?php echo CHtml::activeTextField($item,"[$i]count"); ?></td>
<td><?php echo CHtml::activeTextArea($item,"[$i]description"); ?></td>
<tr>
<?php endforeach;?>
</table>
What I want:- I want to calculate the total working hours of my employees based on the working hours of multiple days.
My problem the total working hours ($total_hours) is not working.
My Model
class Attendence extends AppModel {
function add($data){
if (!empty($data)) {
$this->create();
if($this->save($data)) {
return true ;
}
}
}
function fetchdata() {
return $this->find('all', array('conditions' => array('Attendence.date' > '2014-04-01',
'AND' => array('Attendences.date' < '2014-04-21'),
)));
}
}
My Controller
class EmployeesController extends AppController {
public $uses = array('Employee', 'Attendence', 'InsertDate');
public function add()
{
if($this->Employee->add($this->request->data)==true){
$this->redirect(array('action'=>'index'));
}
}
public function index(){
$this->set('employees',$this->Employee->Fetch());
$this->set('attendence',$this->Attendence->fetchdata());
$this->set('dates',$this->InsertDate->fetchdate());
}
}
My View
<div class="index">
<table>
<thead>
<th>Num</th>
<th>Employee</th>
<th>Salary/Hour</th>
<th>Start Date</th>
<th>End Date</th>
<th>Total Hour</th>
<th>Total Salary</th>
</thead>
<?php
$id = 0;
foreach($employees as $e):?>
<? $id++ ?>
<tr>
<td><?php echo $e{'Employee'}{'id'} ?></td>
<td><?php echo $e['Employee']['firstname'], $e['Employee']['lastname'] ?></td>
<td style="text-align:center"><?php echo $e['Employee']['salary'] ?></td>'
<?php foreach($dates as $d):?>
<td><?php echo $d['InsertDate']['start_date'] ?></td>
<td><?php echo $d['InsertDate']['end_date'] ?></td>
<?php
$total_hours = 0;
foreach ($attendence as $et){
$ts1 = strtotime($et['Attendence']['in_time']);
$ts2 = strtotime($et['Attendence']['out_time']);
$diff = abs($ts1 - $ts2) / 3600;
$total_hours += number_format($diff,2);
}
//Total hours
echo '<td style="text-align:center">'.$total_hours.'</td>';
//Total Salary
echo '<td style="text-align:center">'.$total_hours*$e['Employee']['salary'].'</td>';
?>
<?php endforeach; ?>
<?php endforeach; ?>
</tr>
</table>
</div>
A programmer friend of mine gave me a solution. But I dont know how to implement in CAKEPHP
I am updating the solution also
Look at here :
$total_hours = 0;
foreach ($attendence as $et){
$ts1 = strtotime($et['Attendence']['in_time']);
$ts2 = strtotime($et['Attendence']['out_time']);
$diff = abs($ts1 - $ts2) / 3600;
$total_hours += number_format($diff,2);
}
The code shows you that there is an array. the array contains (attendance id and in_time and out_time in each point).
The Important thing is you should check how you fill this array.
In the above foreach that you generate the table by $employees array , you have the (employee_id) wich name (id) here
So you should write a new query in your view!!!In the middle of your first foreach and before second foreach
before this line :
$total_hours = 0
You have to write a query and fetch data from DB like this :
//SELECT * FROM attendences
WHERE attendences.date > '2014-04-23' AND attendences.date < '2014-04-30'
AND id=$e['Employee']['id'] // is your employee_id in your first array.
So when you fetched data , You have a new array named "$attendence"
Then , your second foreach(which calculates the salary and total hours) should work correctly
I am writing a shopping cart and have my data stored in the $_SESSION array, but would like to calculate a total. below it the code I thought would work to do this, but it returns '1' in stead of a total!
$total = array($_SESSION['qty'],$_SESSION['pr']);
/* I'll give you more code...thanks for your help!!
here is the code for my php cart:
<?php
function item_list()
{
if(isset($_SESSION['qty'])){
$total = array($_SESSION['qty'],$_SESSION['pr']);
foreach($_SESSION['qty'] as $key => $value)
{?>
<tr>
<td align="center"><?php echo $_SESSION['item'][$key]; ?></td>
<td align="center"><?php echo $value; ?></td>
<td align="center"><?php echo $_SESSION['pr'][$key]; ?></td>
<td align="center"><?php echo array_product($total); ?>
</tr><?php
}
}
}
session_start();
if(isset($_POST['clear']) && ($_POST['clear'] == 'clear'))
{
session_destroy();
unset($_SESSION['qty']);
unset($_SESSION['item']);
unset($_SESSION['pr']);
unset($_POST['qty']);
unset($_POST['item']);
unset($_POST['pr']);
}
if(!isset($_SESSION['qty'])) $_SESSION['qty'] = array();
if(!isset($_SESSION['item'])) $_SESSION['item'] = array();
if(!isset($_SESSION['pr'])) $_SESSION['pr'] = array();
if(isset($_POST['qty']))
{
foreach($_POST['qty'] as $value)
{
if(!$value == '') array_push($_SESSION['qty'], filter_var($value,
FILTER_SANITIZE_SPECIAL_CHARS));
}
foreach($_POST['item'] as $key => $value)
{
if(!$_POST['qty'][$key] == '') array_push($_SESSION['item'], filter_var($value,
FILTER_SANITIZE_SPECIAL_CHARS));
}
foreach($_POST['pr'] as $key => $value)
{
if(!$_POST['qty'][$key] == '') array_push($_SESSION['pr'], filter_var($value,
FILTER_SANITIZE_SPECIAL_CHARS));
}
}
?>
That is a strange way to structure a shopping cart, but here's how to do it with that structure:
foreach($_SESSION['qty'] as $key => $value)
{
$total = $_SESSION['qty'][$key] * $_SESSION['pr'][$key];
?>
<tr>
<td align="center"><?php echo $_SESSION['item'][$key]; ?></td>
<td align="center"><?php echo $value; ?></td>
<td align="center"><?php echo $_SESSION['pr'][$key]; ?></td>
<td align="center"><?php echo $total; ?>
</tr><?php
}
If you wanted to get a total of all quantity and cost of the cart:
function getTotals()
{
$total = array('qty' => 0, 'price' => 0);
foreach($_SESSION['qty'] as $key => $qty)
{
$total['qty'] += $qty;
$total['price'] += ($_SESSION['pr'][$key] * $qty)
}
return $total;
}
$total = getTotals();
echo $total['qty']; // output the total quantity of items
echo $total['price']; // output the total cost for all items and quantity
I would recommend a better structure though, something like:
$_SESSION['cart']['items'] = array(
array(
'name' => 'Screwdriver',
'price' => 5,
'qty' => 2,
),
array(
'name' => 'Hammer',
'price' => 10,
'qty' => 1,
)
);
As per your cart array it is not able to hold multiple products you have to use multy dimensional array like this
$_SESSION['cart_items'] = array(
array( "qty"=>5, "item"=>"tshirt", "pr"=>50.20),
array( "qty"=>2, "item"=>"Cell Phone", "pr"=>50.20),
array( "qty"=>7, "item"=>"", "pr"=>50.20),
)
then you can write your code like this
function item_list()
{
foreach($_SESSION['cart_items'] as $item_array)
{?>
<tr>
<td align="center">Item:<?php echo $item_array['item']; ?></td>
<td align="center">Qty: <?php echo $item_array['qty']; ?></td>
<td align="center">Price :<?php echo $item_array['pr']; ?></td>
<td align="center">Total : <?php echo $item_array['qty'] * $item_array['pr']; ?>
</tr><?php
}
}
You should create yourself a Card class that is able to import/export data from the $_SESSION superglobal (or some other array if you mock it for tests, testing with $_SESSION can be akward) which is able to handle your data-structure easily and can calculate the total, too:
$cart = new Cart();
$cart->importFromArray($_SESSION);
// or:
$cart->importFromArray($_SESSION['cart']);
// later on:
$total = $cart->getTotal();
// somewhere else:
$cart->addItem(...);
...
$_SESSION['cart'] = $cart->exportToArray();
That will allow you to more easily change the code over time.