I'm trying to understand recursion :) Well, specifically fetching a full YouTube playlist using Google's PHP Client Library.
This is my function in my class called YTFunctions. It first gets called with a valid, authenticated YouTube_Service object and a playlistId. Then, it should theoretically call itself over and over again as long as the PlaylistItems response has a nextPageToken and then append that to its outputs which should contain all objects (videos) contained in the playlist. For some reason, it just return an empty array.
public static function getFullPlaylistByID($youtube, $playlistId, $pageToken) {
$params = array(
'maxResults' => 50,
'playlistId' => $playlistId,
);
if ($pageToken !== false) {
$params['pageToken'] = $pageToken;
}
$playlistResponse = $youtube->playlistItems->listPlaylistItems('snippet,contentDetails', $params);
error_log(count($playlistResponse['items']));
$playlistItems = $playlistResponse['items'];
if (isset($playlistResponse['nextPageToken'])) {
$playlistItems = array_merge($playlistItems, YTFunctions::getFullPlaylistByID($youtube,$playlistId, $playlistResponse['nextPageToken']));
} else {
}
return $playlistItems;
}
I am clearly missing something here, any help would be greatly appreciated.
Tobias Timpe
here my class that will get all playlistItems
<?php
class yt{
public $DEVELOPER_KEY = '{DEVELOPER_KEY}';
public $client;
public $youtube;
public function __construct(){
$this->client = new Google_Client();
$this->client->setDeveloperKey($this->DEVELOPER_KEY);
$this->youtube = new Google_YoutubeService($this->client);
}
public function getPlaylistItems($playlist, $maxResults, $nextPageToken = ''){
$params = array(
'playlistId' => $playlist,
'maxResults' => $maxResults,
);
// if $nextPageToken exist
if(!empty($nextPageToken)){
//insert $nextPageToken value into $params['pageToken']
$params['pageToken'] = $nextPageToken;
}
$youtubeFeed = $this->youtube->playlistItems->listPlaylistItems('id,snippet,contentDetails', $params);
// function for looping our feed and entry
$this->setFeed($youtubeFeed);
//check if nextPageToken are exist
if(!empty($youtubeFeed['nextPageToken'])){
$insert = $this->getPlaylistItems($playlist, $maxResults, $youtubeFeed['nextPageToken']);
// return to function if nextPageToken are exist
return $insert;
}
}
}
$yt = new yt();
?>
and than use our class
$yt->getPlaylistItems('PL0823049820348','25');
Related
This my first soap code in PHP.
But I dont get any result. I think there is some problems in soapCall and SoapClient.
I have three file.
server , client and service.
I want to connect to server and just get students name by soap. This is so simple code but doesnt work.
//server.php
<?php
class server
{
public function __construct()
{
}
public function getStudentsName($id_array)
{
return 'Mohammad';
}
}
$params = array('uri'=>'phpsoap/server.php');
$server = new SoapServer(NULL , $params);
$server -> setClass('server');
$server -> handle();
?>
//client.php
<?php
class client
{
public function __construct()
{
$params = array('location' => 'http://phpsoap.exp/server.php',
'uri' => 'urn://phpsoap/server.php',
'trace' => 1
);
$this->instance= new SoapClient(NULL , $params);
}
public function getName($id_array)
{
$this->instance->__soapCall('getStudentsName' , $id_array);
}
}
$client = new client;
?>
//service.php
<?php
include './client.php';
$id_array=array('id'=>'1');
echo $client->getName($id_array);
?>
Method client::getName should return value from __soapCall, currently is return void, that's why you don't see anything
public function getName($id_array)
{
return $this->instance->__soapCall('getStudentsName' , $id_array);
}
I try to post an article to Bexio via the Bexio API: https://docs.bexio.com/resources/article/
There is also a sample for PHP: https://docs.bexio.com/samples/
I updated the scopes in the config.php to allow read and write articles.
I updates the bexioConnector.class.php so i can get Articles (works):
public function getArticles($urlParams = array()) {
return $this->call('article', $urlParams);
}
public function call($ressource, $urlParams = array(), $postParams = array(), $method = Curl::METHOD_GET) {
$url = $this->api_url . "/" . $this->org . "/" . $ressource;
$data = $this->curl->call($url, $urlParams, $postParams, $method, $this->getDefaultHeaders());
return json_decode($data, true);
}
So i can use now this code to get all articles (works):
$bexioProducts = $con->getArticles(array('order_by' => 'id'));
Now i want to create articles with the POST method.
So i added this function to the bexioConnector.class.php
public function postArticle($postParams = array(), $urlParams = array()) {
return $this->call('article', $urlParams, $postParams, Curl::METHOD_POST);
}
So i use this code to create a product:
$con->postArticle(array(
'intern_code' => "SKU-3214"
)
);
But this ends in an error:
{"error_code":415,"message":"Could not parse the data."}
I have tried a lot but i always get the same error message.
What could i have don possibly wrong?
I found the error. I need to encode it as a json first.
So i changed my postArticle function:
public function postArticle($postParams = array(), $urlParams = array()) {
$json = json_encode($postParams);
return $this->call('article', $urlParams, $json, Curl::METHOD_POST);
}
I am attempting to add logging for the envelope generated by a third party library. I am modifying the updateMetadataField() method below.
I am creating $client like so:
$client = new UpdateClient($UPDATE_END_POINT, $USER_AUTH_ARRAY);
I have tried both $this->client->__getLastRequest() and $this->__getLastRequest() with the same error as a result.
When the SoapClient is instantiated trace is set to true.
Error is
Fatal error: Call to undefined method UpdateClient::__getLastRequest()
So how do I correctly access the __getLastRequest() method?
$USER_AUTH_ARRAY = array(
'login'=>"foo",
'password'=>"bar",
'exceptions'=>0,
'trace'=>true,
'features' => SOAP_SINGLE_ELEMENT_ARRAYS
);
class UpdateClient {
private $client;
public function __construct($endpoint, $auth_array) {
$this->client = new SoapClient($endpoint, $auth_array);
}
public function updateMetadataField($uuid, $key, $value) {
$result = $this->client->updateMetadataField(array(
'assetUuid' => $uuid,
'key' => $key,
'value' => $value)
);
if(is_soap_fault($result)) {
return $result;
}
return $result->return . "\n\n" . $this->client->__getLastRequest();
} // updateMetadataField()
} // UpdateClient
UPDATE - adding calling code This code iterates over an array which maps our data to the remote fields.
What I am hoping to do is begin storing the envelope we send to aid in debugging.
$client = new UpdateClient($UPDATE_END_POINT, $USER_AUTH_ARRAY);
foreach ($widen_to_nool_meta_map as $widen => $nool) { // array defined in widen.php
if ($nool != '') {
// handle exceptions
if ($nool == 'asset_created') { // validate as date - note that Widen pulls exif data so we don't need to pass this
if (!strtotime($sa->$nool)) {
continue;
}
} else if ($nool == 'people_in_photo' || $nool == 'allow_sublicensing' || $nool == 'allowed_use_pr_gallery') {
// we store as 0/1 but GUI at Widen wants Yes/No
$sa->$nool = ($sa->$nool == '1') ? 'Yes' : 'No';
} else if ($nool == 'credit_requirements') {
$sa->$nool = $sa->credit_requirements()->label;
}
$result = $client->updateMetadataField($sa->widen_id, $widen, $sa->$nool);
if(is_soap_fault($result)) {
$sync_result = $sync_result . "\n" . $result->getMessage();
} else {
$sync_result = $sync_result . "\n" . print_r($result, 1);
}
} // nool field set
} // foreach mapped field
If you want to access UpdateClient::__getLastRequest() you have to expose that method on the UpdateClient class since the $client is a private variable. The correct way of calling it is $this->client->__getLastRequest().
Take a look at this working example, as you can see I'm consuming a free web service for testing purposes.
<?php
$USER_AUTH_ARRAY = array(
'exceptions'=>0,
'trace'=>true,
'features' => SOAP_SINGLE_ELEMENT_ARRAYS
);
class TestClient {
private $client;
public function __construct($endpoint, $auth_array) {
$this->client = new SoapClient($endpoint, $auth_array);
}
public function CelsiusToFahrenheit( $celsius ) {
$result = $this->client->CelsiusToFahrenheit(array(
'Celsius' => $celsius
)
);
if(is_soap_fault($result)) {
return $result;
}
return $result;
}
public function __getLastRequest() {
return $this->client->__getLastRequest();
}
}
try
{
$test = new TestClient( "http://www.w3schools.com/webservices/tempconvert.asmx?wsdl", $USER_AUTH_ARRAY);
echo "<pre>";
var_dump($test->CelsiusToFahrenheit( 0 ));
var_dump($test->__getLastRequest());
var_dump($test->CelsiusToFahrenheit( 20 ));
var_dump($test->__getLastRequest());
echo "</pre>";
}
catch (SoapFault $fault)
{
echo $fault->faultcode;
}
?>
I have been creating a helper class for the Facebook PHP API in order to avoid reusing a lot of code. The helper works but the only problem is that its very slow.. and I also figured out why! when I initialize the class, the constructor is called twice! I checked in my code and the other elements which use this class only call it once (It's something inside the class itself) Could you please help me figure out what the problems could be?? Thanks!
class FbHelper
{
private $_fb;
private $_user;
function __construct()
{
// Initalize Facebook API with keys
$this->_fb = new Facebook(array(
'appId' => 'xxxxxxxxxxx',
'secret' => 'xxxxxxxxxxxxxxxxxxxxxx',
'cookie' => true,
));
// set the _user variable
//
$this->doLog("Called Constructor");
//
$this->_user = $this->UserSessionAuthorized();
return $this;
}
function doLog($text)
{
// open log file <----- THIS GETS CALLED TWICE EVERY TIME I INITIALIZE THE CLASS!!
$filename = "form_ipn.log";
$fh = fopen($filename, "a") or die("Could not open log file.");
fwrite($fh, date("d-m-Y, H:i")." - $text\n") or die("Could not write file!");
fclose($fh);
}
function getUser() { return $this->_user; }
function getLoginUrl() { return $this->_fb->getLoginUrl(); }
function getLogoutUrl() { return $this->_fb->getLogoutUrl(); }
function UserSessionAuthorized()
{
// Checks if user is authorized, if is sends back user object
$user = null;
$session = $this->_fb->getSession();
if (!$session) return false;
try {
$uid = $this->_fb->getUser();
$user = $this->_fb->api('/me');
if ($user) return $user;
else return false;
}
catch (FacebookApiException $e) { return false; }
}
private function _rebuildSelectedFriends($selected_friends)
{
// Creates a new array with less data, more useful and less malicious
$new = array();
foreach ($selected_friends as $friend)
{
$f = array('id' => $friend['id'], 'name' => $friend['name']);
$new[] = $f;
}
return $new;
}
function GetThreeRandomFriends()
{
$friends = $this->_fb->api('/me/friends');
$n = rand(1, count($friends['data']) - 3);
$selected_friends = array_slice($friends['data'], $n, 3);
return $this->_rebuildSelectedFriends($selected_friends);
}
function UserExists($user_id)
{
try { $this->_fb->api('/' . $user_id . '/'); return true; }
catch (Exception $e) { return false; }
}
}
You must be calling the FbHelper class twice as your doLog function is in the constructor, therefore the repetition is somewhere higher up in your application and not in this class itself.
I have a report model which I am using as the main container for all the functions that fetch various report data. This report model has the following functions
protected $_dbTable;
public function setDbTable($dbTable)
{
if (is_string($dbTable))
{
$dbTable = new $dbTable();
}
if (!$dbTable instanceof Zend_Db_Table_Abstract)
{
throw new Exception('Invalid table data gateway provided');
}
$this->_dbTable = $dbTable;
return $this;
}
public function getDbTable($dbTable)
{
if (null === $this->_dbTable)
{
$this->setDbTable($dbTable);
}
return $this->_dbTable;
}
public function agentDailyCollections()
{
//$db =
$sql = $this->getDbTable('Application_Model_DbTable_Groupsloandetails'`enter code here`)->select()
->setIntegrityCheck(false)
->from(array('gl' => 'groups_loan_details'), array())
->join(array('ml' => 'members_loan_details'), 'gl.id = ml.groups_loan_details_id',
array('SUM(ml.daily_payment) AS GroupDailyPayment'))
->join(array('m' => 'members'), 'ml.members_id = m.id', array('id AS ID', 'first_name AS MFirstName', 'surname AS MSurname'))
->join(array('g' => 'groups'), 'gl.groups_id = g.id', array('group_name'))
->join(array('u' => 'users'), 'gl.loan_officer = u.id', array('id AS OID', 'first_name', 'surname'))
->where('gl.loan_end >=?', date(Y.'-'.m.'-'.d))
->where('gl.occur = ?', 'Active')
->group('(u.id)')
->group('(g.group_name)')
->group('(m.id) WITH ROLLUP');
return $this->getDbTable()->fetchAll($sql);
}
public function groupsWithMembers()
{
$sql = $this->getDbTable('Application_Model_DbTable_Members')->select()
->setIntegrityCheck(false)
->from(array('m' => 'members'), array())
->join(array('g' => 'groups'), 'm.groups_id = g.id')
->group('(g.group_area_residence)')
->group('(g.group_name) WITH ROLLUP');
return $this->getDbTable()->fetchAll($sql);
}
In my attempt to have access to different tables as per the different report requirement, I pass the name of the needed table class to the getDbTable function expecting it to get an object of the table for me. It kinda works but then I get the following error message
Warning: Missing argument 1 for Application_Model_Report::getDbTable(), called in D:\www\gepm\application\models\Report.php on line 131 and defined in D:\www\gepm\application\models\Report.php on line 22`enter code here`
I know there is something fundamentally wrong with what I am doing but not sure what. Need help guys just trying to get head round this object/zend framework thing. Thanks.
I think you missed default value for argument on your function, try to change:
public function getDbTable($dbTable)
{
with
public function getDbTable($dbTable = null)
{