I am working on implementing an API interface for my project.
As i know, there are different forms to make pagination through the results, like the following:
https://example.com/api/purchaseorders?page=2&pagesize=25
But, i see many APIs like google use a different approach, in which they use a "pageToken" to let the user move between the pages of results, for example:
https://example.com/api/purchaseorders?pagesize=25&pageToken=ClkKHgoRc291cmNlX2NyZWF0ZWRfYXQSCQjA67Si5sr
So instead of page=2 they used pageToken=[token].
It is not clear for me the idea of pageToken and how to implement it.
It will be helpful if you guide me to any resources so i can get more knowledge.
Thank you.
Here's a very simple standalone example using the filesystem as a keyvalue store (since a filesystem will always be available).
$requestParameters = [];
if (($token = filter_input(INPUT_GET,"pageToken")) && is_readable("/tmp/$token")) {
$requestParameters = file_get_contents("/tmp/$token");
} else {
$requestParameters = [
"q" => filter_input(INPUT_GET,"q"),
"pageSize" => filter_input(INPUT_GET,"pageSize",FILTER_VALIDATE_INT),
"page" => filter_input(INPUT_GET,"page",FILTER_VALIDATE_INT)
];
}
$nextPageRequestParameters = $requestParameters;
$nextPageRequestParameters["page"]++;
$nextPageToken = md5(serialize($nextPageRequestParameters)); //This is not ideal but at least people can't guess it easily.
file_put_contents("/tmp/$nextPageToken", serialize($nextPageRequestParameters));
//Do request using $requestParameters
$result = [ "nextPageToken" => $nextPageToken, "data" => $resultData ];
echo json_encode($result);
Related
I'm using alaouy/youtube package for one of my projects, Its working just fine, But with this method I can't use pagination! Is there any way or I've to write my own code? There is a vendor folder in my resources with pagination folder but I can't get work with it!
// List videos in a given channel, return an array of PHP objects
$videoList = Youtube::listChannelVideos('UCk1SpWNzOs4MYmr0uICEntg', 40);
I'm the creator of that package, happy that it was helpful for you and sorry that the documentation wasn't clear enough.
The listChannelVideos is based on the searchAdvanced method, so you can paginate the channel videos like this :
$params = array(
'channelId' => 'UCk1SpWNzOs4MYmr0uICEntg',
'type' => 'video',
'part' => 'id, snippet',
'maxResults' => 40);
// Make intial call. with second argument to reveal page info such as page tokens
$search = Youtube::searchAdvanced($params, true);
print_r($search); // First page results
// Check if we have a pageToken
if (isset($search['info']['nextPageToken'])) {
$params['pageToken'] = $search['info']['nextPageToken'];
}
// Make another call and repeat
$search = Youtube::searchAdvanced($params, true);
print_r($search); // Second page results
Hope this will help you!
I am trying to clean up my site by putting all of my configurations in one place for easy access.
I have many different configuration dependencies for example, PayPal and Stripe public/private and sandbox/live keys as well as a number of links e.g. google recaptcha links.
I don't want to be spreading these keys around my app and then need to go hunting for them if I want to go from sandbox to live for example.
I am trying to define my API keys and most used links in the CodeIgniter config.php file like this...
$config['stripe_live'] = [
'secret' => 'secret_key_xyz',
'private' => 'private_key_xyz',
]
$config['stripe_sandbox'] = [
'secret' => 'secret_key_xyz',
'private' => 'private_key_xyz',
]
$config['paypal'] = [
'secret' => 'secret_key_xyz',
'private' => 'private_key_xyz',
]
$config['recaptcha'] = [
'site_key' => 'xyz_one_two_three',
'secret_key' => 'xyz_one_two_three',
];
$config['jquery'] = [
['jquery_link'] => base_url() . 'Public/js/jquery.js',
]
$config['bootstrap'] = [
['bootstrap_link'] => base_url() . 'Public/js/jquery.js',
]
$config['fontawesome'] = [
]
$config['google_fonts'] = [
];
$config['groupworld'] = [
'groupworld_api' => 'api_key_xyz';
];
Question one:
If I wanted to access my Stripe live private key I would have to write...
$stripe_live = $this->config->item('stripe_live');
$stripe_live['public_key'];
This is almost as much work as just copying the key to where I need it (one or two places). So is there a simpler way?
Question two:
Is is okay to put my urls in the config file like in my example above? Or would it be better to define my URLs as constants (in the constants file) and then simply access them as constants instead of writing out $this->config->item('bootstrap_link')
Thanks.
After looking at the CodeIgniter Config documentation I have come up with the following solution at least for my API configuration settings, in the example below I am using the google recaptcha API.
1 - Make a new file inside of the application/config folder and call it whatever you want... e.g. api_config.php
Inside this file put your API keys like this:
// stripe api
$config["stripe_live_public_key"] = "public_key_xyz";
$config["stripe_live_private_key"] = "public_key_xyz";
$config["stripe_sandbox_public_key"] = "public_key_xyz";
$config["stripe_sandbox_private_key"] = "public_key_xyz";
// paypal api
$config["paypal_live_public_key"] = "public_key_xyz";
$config["paypal_live_private_key"] = "public_key_xyz";
$config["paypal_sandbox_public_key"] = "public_key_xyz";
$config["paypal_sandbox_private_key"] = "public_key_xyz";
// recaptcha api
$config["recaptcha_api_url"] = 'https://www.google.com/recaptcha/api.js';
$config["recaptcha_verification_url"] = "https://www.google.com/recaptcha/api/siteverify";
$config["recaptcha_public_key"] = "lfgksl;dfg;kkkkdsjfhskjfhkjsdhfjshjksjdh";
$config["recaptcha_private_key"] = "sfkljslfjsjfahjjjjjjhjhsdfjskhajkakkajdj";
// groupworld api
// phpmailer api
2 - In the controller file load your config file and mass the data to the view like this...
$this->config->load('api_config');
$data['recaptcha_api_url'] = $this->config->item('recaptcha_api_url');
$data['recaptcha_public_key'] = $this->config->item('recaptcha_public_key');
3 - In the view file simply display your data...
<script src="<?php echo $recaptcha_api_url; ?>"></script>
<div class="g-recaptcha" data-sitekey="<?php echo $recaptcha_public_key; ?>"></div>
Now to change your config data in multiple places simply go to the api_config.php file and paste in your new keys.
As I'm a newbie can't comment :/ .
I will start with question 2. Its ok to keep like this. But stripe,paypal are payment gateways it will be good to store it in db as Yogesh said and retrieve to use it.It will also comes in handy if you want to provide user to edit it.
For js,css links you can put them in a view like 'includefiles.php' and load it in all pages as we load views.
for easy retrieval of your data, you can use helper functions.
<?php
//paymentdetail_helper
function getpaymentdetailhelper(someid or gateway name as arg eg.$id){
$ins=& get_instance();
$ins->load->database();
//your queries $ins->db->query();
return $data;
}
?>
Save this in application/helpers as paymentdetail_helper.php and load it as usual. more info about helpers in questionInfo about helper
Its my idea. :) You're welcome with suggestions
Given that I have a WHMCS addon that I call 'my_addon'. I created the main addon file 'my_addon.php' which does contain nothing than:
<?php
function my_addon_clientarea($vars) {
$client = null;
return array(
'pagetitle' => 'My Addon',
'breadcrumb' => array('index.php?m=my_addon'=>'My Addon'),
'templatefile' => 'views/myaddon_view',
'vars' => array(
'client' => $client
)
);
}
This does basically work. It does give me my template file, everything is passed through. My question is: How do I get the currently logged in client from within that function?
I didn't find any API method and I can't see any constant which does hold this information.
There must be a way to get the current client within the clientarea? Thanks for your help!
For those who do come after me and have the same problem: it's easy to solve. Turned out, that I just had to think it through... I found the client id to be available in the $_SESSION-variable.
So, if you are looking for the client's id:
<?php
function my_addon_clientarea($vars) {
$clientid = $_SESSION['uid'];
// And so on...
}
The official way to get current user information is:
$currentUser = new \WHMCS\Authentication\CurrentUser;
$user = $currentUser->user();
You can find more information here
Does anyone know how to fetch all facebook ads statistics and display on webpage using Facebook Ads Api-PHP SDK. I am using this API and I am getting campaign details like name of campaign, id, status. but not able to get impressions,clicks, spent.
What I am doing let me share with you:
1) I am getting access token by authorizing user
2) After getting access token, I am using below code
$account = new AdAccount('act_XXXXXXXXXXXXXXX');
$account->read();
$fields = array(
AdCampaignFields::ID,
AdCampaignFields::NAME,
AdCampaignFields::OBJECTIVE,
);
$params = array(AdCampaignFields::STATUS => array(AdCampaign::STATUS_ACTIVE,AdCampaign::STATUS_PAUSED,),);
$campaigns = $account->getAdCampaigns($fields, $params);
/* Added By Jigar */
$campaign = new AdCampaign('XXXXXXXXXXXXXXXX');
$compainDetails = $campaign->read($fields);
3) then printing the array
echo "<pre>";
print_r($compainDetails);
exit;
If anyone know any suggestion in above code, please share. All code is in PHP. Dose anyone have any tutorial that fetch all above required data then share it
You could try to use the facebook insights api instead of $campaign->read. Here's an example:
https://developers.facebook.com/docs/marketing-api/insights/v2.5#create-async-jobs
What you have to do to get impressions, click and spent is to add these fields to the $fields param. In your case, the complete code should look like the following:
use FacebookAds\Object\Campaign;
use FacebookAds\Object\Values\InsightsLevels;
use FacebookAds\Object\Values\InsightsFields;
$campaign = new Campaign();
$fields = array(
InsightsFields::IMPRESSIONS,
InsightsFields::UNIQUE_CLICKS,
InsightsFields::CALL_TO_ACTION_CLICKS,
InsightsFields::INLINE_LINK_CLICKS,
InsightsFields::SOCIAL_CLICKS,
InsightsFields::UNIQUE_SOCIAL_CLICKS,
InsightsFields::SPEND,
);
$params = array(
'level' => InsightsLevels::CAMPAIGN,
);
$async_job = $campaign->getInsightsAsync($fields, $params);
$async_job->read();
I don't know what exactly the "click" param means for you, but if you take a look at all these click params, I'm sure you'll find it or you'll know how to calculate it.
For a complete list of fields available on insights objects, have a look at: https://github.com/facebook/facebook-php-ads-sdk/blob/master/src/FacebookAds/Object/Fields/InsightsFields.php
Hope that helps.
Regards, Benjamin
I'm learning OOP a little and I want to get myself some good habits.
I'm writing an app which uses 'components'.
Each component is being included in component View, when $_GET['component_name'] is proper.
Components are placed in /components/component_name/ and contains files like index.php, helper.php, controller.php.
I'm doing index.php this way:
$name = "newsModule";
$helper = $name."Helper";
global $component;
$component = new $name;
$component->name = $name;
$component->template = 1;
$component->prefix = "com_";
$component->legend = array(
"time" => "create date",
"edit" => "edit",
"remove" => "delete"
);
$component->db = $component->prefix.$name;
$component->id = $_GET['id'];
$component->itemList = $helper::itemList(array(
'fields' => '*',
'db' => $component->db,
'where-field' => "title",
'where-value' => $_SESSION['keywords_'.$name]
));
Now, the $component is visible in Component View in $GLOBALS array, so I do:
$c = $GLOBALS['component'];
and using $c->db for example. And it works.
But finally - what's my point? I just think this solution is not good enough, no-oop enough etc.
I wonder if someone could share some good practices, some info and ideas about how could this code be better.
Thank you
Try these links for a good solid introduction to OOP in php.
http://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762
http://www.tutorialspoint.com/php/php_object_oriented.htm
And as for good habits, find a good working example that more or less does what you want and tweak it to your needs. If you write from scratch you'll quite likely fall flat on your face at every opportunity (speaking from experience).