Xero Create new Tracking Option - php

I can't seem to get tracking options created, the Category itself is creating fine.
However firstly - I should point out I believe there is a bug in the Xero-API for PHP, when debugging adding an option according to the documentation here the PUT should be
https://api.xero.com/api.xro/2.0/TrackingCategories/{TrackingCategoryID}/Options
However in the php lib it is
https://api.xero.com/api.xro/2.0/TrackingCategories/{TrackingCategoryID}/TrackingOptions
Even when that is resolved, I get no error however not tracking Option is created, any ideas?
$options = ['US', 'UK'];
$title = 'Region';
$trackingCategory = null;
if(!$trackingCategory) {
$trackingCategory = new \XeroPHP\Models\Accounting\TrackingCategory($xero);
$trackingCategory->setName($title);
$trackingCategory->save();
}
try {
foreach($options as $option) {
$to = new \XeroPHP\Models\Accounting\TrackingCategory\TrackingOption($xero);
$to->setName($option);
$trackingCategory->setOption($option);
$trackingCategory->save();
}
} catch(\Exception $e) {
$this->logger()->info($e->getTraceAsString());
$this->logger()->info("TRACKING: ". $e->getMessage());
return false;
}

So this would appear it is a bug as reported here
The source has not been fixed, however the above link resolves the problem for anyone else searching.

Changing TrackingOptions to Options in XeroPHP worked soughta... but I was still getting a different error. Ended up creating the Option manually
Note: $this->_xero_oauth_object is my \XeroPHP\Application\PublicApplication from authentication
// Create the URL object based on an absolute URL
$url = new \XeroPHP\Remote\URL($this->_xero_oauth_object, "https://api.xero.com/api.xro/2.0/TrackingCategories/{TrackCategoryGuid}/Options");
// Pass this to the request as a PUT request
$request = new \XeroPHP\Remote\Request($this->_xero_oauth_object, $url, \XeroPHP\Remote\Request::METHOD_PUT);
// Probably a better way but I just copied and paste the XML from the Xero API docs.
$request->setBody("<Options><Option><Name>My New Option Name</Name></Option></Options>");
// I wrapped this in a try - if it exists, there will be an error as you cant have duplicates.
try {
$request->send();
} catch (Exception $e) {
\Log::warn("Xero error: " . print_r($request->getResponse(), true));
}
// now option is created, new add the option to the tracking category
$tracking = new \XeroPHP\Models\Accounting\TrackingCategory($this->_xero_oauth_object);
$tracking->setTrackingCategoryID('3fceedc7-764e-490a-ac27-25684473af78');
// tracking category name - not sure if I need this
$tracking->setName('Contractor');
// match the option name above
$tracking->setOption('My New Option Name');

Related

Google Speech to Text api client return without exception but no actual results

I am using sample code from googles site and this throws no exceptions but returns no results.
If I use the API explorer the same data works just fine. I have tried different files (all from google sample code) different settings. All of which give me the same result, Nothing.
function transcribe_sync($content)
{
// set string as audio content
$audio = (new RecognitionAudio())
->setContent($content);
// set config
$encoding = AudioEncoding::LINEAR16;
$sampleRateHertz = 32000;
$languageCode = 'en-US';
$config = (new RecognitionConfig())
->setEncoding($encoding)
->setSampleRateHertz($sampleRateHertz)
->setAudioChannelCount(1)
->setMaxAlternatives(1)
->setLanguageCode($languageCode);
// create the speech client
$client = new SpeechClient();
try {
$response = $client->recognize($config, $audio);
echo $response->getResults()
}
catch (\Exception $e) {
$this->handleError('Error determining recognition. ' . $e->getMessage());
}
finally {
$client->close();
}
My resolution to this issues was the way I was passing the file (don't think the file was being populated correctly or at all). It was weird that I did not get an error. Because of the length of my audio files, I ended up integrating google storage to upload the file () and used:
$audio = (new RecognitionAudio())->setUri("gs://...");
... longRunningRecognize($config, $audio);
Hope this helps someone.

getId() method is undefined in sandbox Square Checkout API script

I'm hoping to get a little assistance with something that is probably pretty basic -- I'm attempting to deploy the Square Checkout API with my website. I've been able to successfully install the SDK, and I've used it to successfully pull my sandbox location ID, to test it's function.
I've proceeded to build a page employing only the demo script on the Checkout API page, as seen below:
<?php
#Set the required includes globally
require_once '../config.php';
require INC_PATH . '/squareup/autoload.php';
/*
** Script for submitting payment information
** Utilizing Square API documentation at:
** https://docs.connect.squareup.com/payments/checkout/setup
*/
//Replace your access token and location ID
$accessToken = '<MY SANDBOX KEY>'; // Sandbox
$locationId = '<MY SANDBOX LOCATION ID>'; // Sandbox
// Create and configure a new API client object
$defaultApiConfig = new \SquareConnect\Configuration();
$defaultApiConfig->setAccessToken($accessToken);
$defaultApiClient = new \SquareConnect\ApiClient($defaultApiConfig);
$checkoutClient = new SquareConnect\Api\CheckoutApi($defaultApiClient);
//Create a Money object to represent the price of the line item.
$price = new \SquareConnect\Model\Money;
$price->setAmount(600);
$price->setCurrency('USD');
//Create the line item and set details
$book = new \SquareConnect\Model\CreateOrderRequestLineItem;
$book->setName('The Shining');
$book->setQuantity('2');
$book->setBasePriceMoney($price);
//Puts our line item object in an array called lineItems.
$lineItems = array();
array_push($lineItems, $book);
// Create an Order object using line items from above
$order = new \SquareConnect\Model\CreateOrderRequest();
$order->setIdempotencyKey(uniqid()); //uniqid() generates a random string.
//sets the lineItems array in the order object
$order->setLineItems($lineItems);
## STEP 2: Create a checkout object
$checkout = new \SquareConnect\Model\CreateCheckoutRequest();
$checkout->setIdempotencyKey(uniqid()); //uniqid() generates a random string.
$checkout->setOrder($order); //this is the order we created in the previous step
try {
$result = $checkoutClient->createCheckout(
$locationId,
$checkout
);
//Save the checkout ID for verifying transactions
$checkoutId = $result->getId();
//Get the checkout URL that opens the checkout page.
$checkoutUrl = $result->getCheckoutPageUrl();
print_r('Complete your transaction: ' + $checkoutUrl);
}
catch (Exception $e) {
echo 'Exception when calling CheckoutApi->createCheckout: ', $e->getMessage(), PHP_EOL;
}
I get a 500 error from my webserver when attempting to run this script through my browser, in my httpd error_log I get the following error message:
PHP Fatal error: Uncaught Error: Call to undefined method SquareConnect\\Model\\CreateCheckoutResponse::getId() in <LOCATION>:62\nStack trace:\n#0 {main}\n thrown in <LOCATION> on line 62
Any thoughts on why the getId() method is undefined? Thanks.
UPDATE
I commented out the function calls after the createCheckout() portion of the try{} block, and then ran a var_dump() on $result to make sure I was in fact getting some sort of response. I am getting back the expected result! So I KNOW the API/SDK is working now, I just can't figure out why the $result object is unable to accept the follow-up functions.
Revised try block:
try {
$result = $checkoutClient->createCheckout(
$locationId,
$checkout
);
/*
//Save the checkout ID for verifying transactions
$checkoutId = $result->getId();
//Get the checkout URL that opens the checkout page.
$checkoutUrl = $result->getCheckoutPageUrl();
print_r('Complete your transaction: ' + $checkoutUrl);
*/
}
catch (\Exception $e) {
echo 'Exception when calling CheckoutApi->createCheckout: ', $e->getMessage(), PHP_EOL;
}
var_dump($result); //test to see if any non-zero response to createCheckout() function.
Any thoughts based on this revision? -A
The CreateCheckoutResponse doesn't have the getId() function. It has getCheckout() and getErrors(). So you need to:
$checkoutId = $result->getCheckout()->getId();
Reference: https://github.com/square/connect-php-sdk/blob/master/docs/Model/CreateCheckoutResponse.md
Current Solution:
function objectToArray ($object) {
if(!is_object($object) && !is_array($object))
return $object;
return array_map('objectToArray', (array) $object);
}
$result_array = objectToArray($result);
echo '<pre>';
var_dump($result_array); //test to see if any non-zero response to createCheckout() function.
echo '</pre>';
Since I am getting a valid object back, and all I need to do is extract the ID and checkout URL's from the $result object, I used the function above to convert the object to an array, and from here I'll extract the information I need by key => Value pairing. It's ugly, and it doesn't solve why these post API-call functions included with the SDK aren't working, but it's meeting my immediate solution.
If anyone can tell me what actually happened that prevented the SDK function calls from being defined, I'd appreciate it.

PHP autoload.php not found

so this is my code:
<?php
echo 'hey1';
set_time_limit(0);
date_default_timezone_set('UTC');
echo 'hey2';
require __DIR__.'/../vendor/autoload.php';
echo 'hey3';
/////// CONFIG ///////
$username = 'NetsGets';
$password = 'NetsGetsWebsite';
$debug = true;
$truncatedDebug = false;
//////////////////////
$ig = new \InstagramAPI\Instagram($debug, $truncatedDebug);
try {
$ig->login($username, $password);
} catch (\Exception $e) {
echo 'Something went wrong: '.$e->getMessage()."\n";
exit(0);
}
try {
$feed = $ig->discover->getExploreFeed();
// Let's begin by looking at a beautiful debug output of what's available in
// the response! This is very helpful for figuring out what a response has!
$feed->printJson();
// Now let's look at what properties are supported on the $feed object. This
// works on ANY object from our library and will show what functions and
// properties are supported, as well as how to call the functions! :-)
$feed->printPropertyDescriptions();
// The getExploreFeed() has an "items" property, which we need. As we saw
// above, we should get it via "getItems()". The property list above told us
// that it will return an array of "Item" objects. Therefore it's an ARRAY!
$items = $feed->getItems();
// Let's get the media item from the first item of the explore-items array...!
$firstItem = $items[0]->getMedia();
// We can look at that item too, if we want to... Let's do it! Note that
// when we list supported properties, it shows everything supported by an
// "Item" object. But that DOESN'T mean that every property IS available!
// That's why you should always check the JSON to be sure that data exists!
$firstItem->printJson(); // Shows its actual JSON contents (available data).
$firstItem->printPropertyDescriptions(); // List of supported properties.
// Let's look specifically at its User object!
$firstItem->getUser()->printJson();
// Okay, so the username of the person who posted the media is easy... And
// as you can see, you can even chain multiple function calls in a row here
// to get to the data. However, be aware that sometimes Instagram responses
// have NULL values, so chaining is sometimes risky. But not in this case,
// since we know that "user" and its "username" are always available! :-)
$firstItem_username = $firstItem->getUser()->getUsername();
// Now let's get the "id" of the item too!
$firstItem_mediaId = $firstItem->getId();
// Finally, let's get the highest-quality image URL for the media item!
$firstItem_imageUrl = $firstItem->getImageVersions2()->getCandidates()[0]->getUrl();
// Output some statistics. Well done! :-)
echo 'There are '.count($items)." items.\n";
echo "The first item has media id: {$firstItem_mediaId}.\n";
echo "The first item was uploaded by: {$firstItem_username}.\n";
echo "The highest quality image URL is: {$firstItem_imageUrl}.\n";
} catch (\Exception $e) {
echo 'Something went wrong: '.$e->getMessage()."\n";
}
?>
After running this code, the only things that print are hey1 and hey2. Based on my own reasearch, I concluded that autoload.php is one of the necessery files for the composer to run, but it also seems to be the problem that stops the php from running. This code is from https://github.com/mgp25/Instagram-API. Pease help!
1) If you don't have Composer, install it. For example:
sudo apt-get install composer -y
2) Run:
composer require mgp25/instagram-php
3) Type:
cd vendor
ls
The very first file you see listed should be autoload.php.

How should I properly handle non-cursor pagination with the Facebook PHP SDK?

I am using a few of the Facebook Graph API methods that have pagination successfully using cursor-based pagination, similar to this:
echo '<ul>';
$params = array('limit' => 10);
do {
$groups = (new FacebookRequest(
$session, 'GET', '/me/groups', $params
))->execute()->getGraphObject();
if (null !== $groups->getProperty('paging') && null != $groups->getProperty('paging')->getProperty('next')) {
$params = array('limit' => 10, 'after' => $groups->getProperty('paging')->getProperty('cursors')->getProperty('after'));
} else {
$params = null;
}
foreach ($groups->getProperty('data')->asArray() as $group) {
echo '<li>' . $group->name . '</li>';
}
} while ($params !== null);
echo '</ul>';
This simple code will grab all the groups of the current user. It checks that the paging and paging/next properties are present and if so uses the cursor to setup another iteration of the loop. I realise now this could probably have been done better as the cursor isn't always available. When I use the /{group-id}/feed API endpoint there are the previous and next links but no cursor.
So, how am I supposed to make paginated requests when there is no cursor with the Facebook PHP SDK?
I see other answers suggesting using cURL or even file_get_contents to grab the next and previous URLs but that seems very silly considering I'm using the PHP SDK here - surely there's a built-in way?
I'm using facebook/php-sdk-v4 with Composer - there doesn't seem to be the (old?) $facebook->api(...) functionality availble here either.
Have a look at
https://developers.facebook.com/docs/php/FacebookResponse/4.0.0
There is a method getRequestForNextPage() in the PHP SDK v4.0.0.
// A FacebookResponse is returned from an executed FacebookRequest
try {
$response = (new FacebookRequest($session, 'GET', '/me'))->execute();
// You can get the request back:
$request = $response->getRequest();
// You can get the response as a GraphObject:
$object = $response->getGraphObject();
// You can get the response as a subclass of GraphObject:
$me = $response->getGraphObject(GraphUser::className());
// If this response has multiple pages, you can get a request for the next or previous pages:
$nextPageRequest = $response->getRequestForNextPage();
$previousPageRequest = $response->getRequestForPreviousPage();
} catch (FacebookRequestException $ex) {
echo $ex->getMessage();
} catch (\Exception $ex) {
echo $ex->getMessage();
}
By looking at the source code at
https://github.com/facebook/facebook-php-sdk-v4/blob/4.0-dev/src/Facebook/FacebookResponse.php#L164
it just handles the next property:
return $this->handlePagination('next');
IMHO, using the next property as a default should be fine, opposed to cursors. Furthermore, I don't even see a cursors property when querying a sample group's feed, so this might be obsolete.
References:
https://developers.facebook.com/docs/graph-api/using-graph-api/v2.3#paging

Mediawiki stopping a page from saving and redirecting back to edit page with an error message

My wiki articles contain a link to a specific dataset. I want to enforce that these links are unique (as in no one can create a new page with a link that is present in another page.) I have already written most of the code for this extension. I created a table 'unique_external_links' that stores the url as an index and the page id that the URL lives in.
Here is a part of the code I wrote:
$wgHooks['ParserFirstCallInit'][] = 'UniqueURLSetupParserFunction';
$wgHooks['LoadExtensionSchemaUpdates'][] = 'fnExternalLinksDBHook';
// Allow translation of the parser function name
$wgExtensionMessagesFiles['UniqueUrl'] = dirname( __FILE__ ) . '/UniqueUrl.i18n.php';
// Tell MediaWiki that the parser function exists.
function UniqueURLSetupParserFunction( &$parser ) {
$parser->setFunctionHook( 'example', 'UniqueURLParserFunction' );
return true;
}
function UniqueURLParserFunction( $parser, $param1 = '', $param2 = '' ) {
// The input parameters are wikitext with templates expanded.
// The output should be wikitext too.
global $wgRequest, $wgOut;
$return_url = $wgRequest->getRequestURL();
$pid = $param2;
$param1 = trim($param1);
$url_pattern = '/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/';
$match = preg_match($url_pattern, $param1);
if (!$match) {
// return ERROR not a valid URL!
}
$patterns = array('/^(https?:\/\/)/', '/\/$/');
$replace = array('','');
$url = preg_replace($patterns, $replace, $param1);
if (empty($param2)) { // creating a new page
try {
$dbw = wfGetDB( DB_MASTER );
$res = $dbw->insert('unique_external_links',
array('link_url' => $url , 'page_id' => $pid));
} catch(Exception $e) {
// return ERROR page with this link already exists!
}
} else { //Trying to edit existing page
$dbr = wfGetDB( DB_SLAVE );
$res = $dbr->select(
'unique_external_links',
array( 'link_url' ),
'link_url = "' .$url.'" AND page_id = "' .$pid.'"'
);
if ($dbr->numRows($res) == 0) {
try {
$dbw = wfGetDB( DB_MASTER );
$res = $dbw->insert('unique_external_links',
array('link_url' => $url , 'page_id' => $pid));
} catch(Exception $e) {
//return ERROR Dataset Already Exists
$response = $wgRequest -> response();
$response -> header('Location: '.$return_url);
return $return_url;
}
}else {
//just editing page, not changing link, all is good
return $param1;
}
}
return $param1;
}
First off, I apologize for the sloppy code, really just slapped this together very quickly with no prior extension experience...
As you can see there are places where I have the comment //return ERROR I would like to stop media wiki from saving the page if one of those conditions are true. Instead of saving, I would like to return the user to the edit page with a message telling them there is a problem with the link they are providing.
Any ideas? I looked around a lot but couldn't find anything similar, I assume it is because I don't know really what question to ask. I am aware that there are hooks like 'ArticleSave', but i didn't know how I would use that in conjunction with a parser.
Any help would be great! Even if its telling me to completely re-do what I did because its all wrong haha.
EDIT: I fixed this problem by throwing MWExceptions at those places where I wanted to return an error. I then went to Exceptions.php and updated the MWExceptionhandler to take a different action when it sees that the exception message matches the ones I am throwing from this extension. This is hacky I admit.. But what can you do sometimes..
Writing this extension as a parser function is probably the wrong direction. If you want to reject edits, use the EditFilter hook. You may want to take a look at the SpamBlacklist extension as a model, as it also looks at links to decide whether to reject an edit.
Also, the one issue I see with your extension is that, once a page has been saved with one of these unique links, there's nothing in place to remove rows from unique_external_links even if the link (or the entire page!) is removed, making it sometimes impossible to reinsert a link that's been removed. You'll probably want to fix that.

Categories