I have a problem in PHP and I can't seem to solve it. I am using Google AdWords API to create campaigns. So first of all I create a new Campaign, and after that new GroupAd. Problem is that I get campaign ID when creating campaign, and although I save that ID in variable $mycampaignID, I can't use it in another class where I am creating GroupAd. Can someone help me with this? I tried using global variable, public variable, etc., but none of it seems to work properly. Here is just a part of the code, you can see how classes and function look like.
class AddCampaigns
{
public static function runExample(
AdWordsServices $adWordsServices,
AdWordsSession $session
) {
$result = $campaignService->mutate($operations);
foreach ($result->getValue() as $campaign) {
**$mycampaignID** = $campaign->getId();
printf(
"Campaign with name '%s' and ID %d was added.\n",
$campaign->getName(),
$campaign->getId()
);
}
}
}
AddCampaigns::main();
class AddAdGroups
{
const CAMPAIGN_ID = **$mycampaignID**;
public static function runExample(
AdWordsServices $adWordsServices,
AdWordsSession $session,
$campaignId
) {
$adGroupService = $adWordsServices->get($session, AdGroupService::class);
}
}
AddAdGroups::main();
Related
I have this class
class Api extends \Magento\Framework\Model\AbstractModel
{
public function __construct(
\Magento\Framework\Message\ManagerInterface $messageManager,
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\MyModule\Payment\Helper\Data $helper
) {
$this->messageManager = $messageManager;
$this->scopeConfig = $scopeConfig;
$this->storeManager = $storeManager;
$this->helper = $helper;
$this->contentType = $this->helper->getConfigData('content_type');
}
.
.
.
function createOnlinePurchase($authToken, $lastOrder)
{
.
.
.
//here I pass lastOrder's increment id to my payment gateway
$lastOrder->setData('test','test data');
$lastOrder->save();
//make payment gateway api call, get payment url
return url;
}
}
this class is then used by a custom controller:
class Index extends \Magento\Framework\App\Action\Action
{
public function __construct(
\Magento\Framework\App\Action\Context $context,
\MyModule\Payment\Model\Api $moduleApi,
\Magento\Checkout\Model\Session $session
) {
parent::__construct($context);
$this->moduleApi = $moduleApi;
$this->session = $session;
}
public function execute() {
$token = $this->moduleApi->requestAuthToken();
if ($this->session->getLastRealOrder() && $token !== null) {
$url = $this->moduleApi->createOnlinePurchase($token, $this->session->getLastRealOrder());
if ($url !== null && substr($url, 0, 4) == 'http') {
$this->session->clearStorage();
return $this->resultRedirectFactory->create()->setUrl($url);
}
else {
$this->messageManager->addError(__("Url invalid: ".$url));
return $this->resultRedirectFactory->create()->setPath('checkout/onepage/failure');
}
}
}
on a SECOND custom controller Callback, which is triggered by my payment gateway, I retrieved the order object using $order = $this->getOrderFactory->create()->loadByIncrementId($incrementId)
where $this->getOrderFactory is an instance of \Magento\Sales\Model\OrderFactory I injected.
I got the increment id back from my payment gateway.
Somehow within this Callback class, when I use $order->getData('test'), I get nothing
My question is
Is there some core magento concept I'm missing here?
Or is there any other way I can retrieve this test data in Callback which only have the information of increment Id (because at the point of Callback, user have already left magento and come back)
It's weird to me beause I can edit and save the order from Callback but my extra data is not saved/associated with the order object itself
Thanks in advance!
UPDATE
I confirmed that I'm getting the same order object(row) by using the order id I get from my payment gateway as the one from session's Last Order
I called addStatusHistoryComment on lastOrder in Api class above and also called addStatusHistoryComment in my Callback class
both calls are updating the same order in my admin dashboard
I have also confirmed calling getData('test') right after I set it gives me the data I want.
So I don't understand why getData doesn't work when called from Callback
You can't just add data to order object, every model is mapped automatically to DB tables columns, object will store temporarily the data and not error out but it will not persist in database. The reason why comments work, is because they have a place in database and on save and on load there is extra code that saves and adds it to the model.
In order to persists new data in the order you need to add new order attribute or simply add a new column on sales order table. When saving, key much match exactly the name of the new column you created.
I ended up using setCustomerNote in place of setData with a custom key, which is weird that it works because it is literally doing:
return $this->setData(OrderInterface::CUSTOMER_NOTE, $customerNote);
I can only assume on magento 2.4.x (which is what i'm using btw), setData is restricted to predefined keys only.
I am new to PHP generally and caching and am trying to develop a Facebook share counter for Wordpress. As advised by a member here, since it's not optimum to make calls to the API and slow down the website each time, I decided to cache the results and went with the static method. Here's the code I am using.
function fb_cache($atts) {
$url = $atts['url'];
static $fb_cache = array();
if (isset($fb_cache[$url])) {
$fb_count = $fb_cache[$url];
return $fb_count;
} else {
$fb = json_decode( file_get_contents('http://graph.facebook.com/' . $url) );
$fb_count = $fb->share->share_count;
$fb_cache[$url] = $fb_count;
return $fb_count;
}
}
This doesn't seem to work as the number keeps changing every few seconds and the API calls are thus being made each time. To use it as a plugin, I also have an instantiating code in the end.
static function get_instance() {
static $instance = false;
if ( ! $instance ) {
$instance = new self;
}
}
Can someone tell me what I am doing wrong. I apologize if it's a noob question and if I am using the wrong method altogether.
I want to retrieve the CC number from authorize.net and display it in sugarcrm v6.5 my problem now is that in the documentation found in authorize.net the code is meant for native PHP. And I just started learning sugarcrm, now what I want to learn is how do I use the code in their document to match sugarcrm.
this it the link to their code I want to use link here
this is my current implementation. And I get this error in sugarcrm: "There was an error processing your request, please try again at a later time."
<?php
require_once("include/MVC/View/views/view.detail.php");
use CB\Integrations\Provider\AuthorizeNet;
class CB_PaymentProfilesViewDetail extends ViewDetail
{
var $contacts_warning;
var $company_logo_path;
var $company_tagline;
var $provider;
public function __construct()
{
global $sugar_config;
$settings = $sugar_config["authorizenet_settings"];
$this->provider = new AuthorizeNet();
$this->provider->auth($settings["appName"], $settings["transactionKey"]);
parent::ViewDetail();
}
function preDisplay() {
$this->contacts_warning = 'Our contacts database is not for personal use. Please do not use it for things not strictly related to company business. You know who you are!';
$this->company_tagline = 'Serving the biggest and brightest stars in Hollywood!';
parent::preDisplay();
}
public function display()
{
$this->provider->setCustomerProfileId(40843288);
echo '<div align="center" style="font-color: red">'.$this->provider->getCustomerPaymentProfileId() .'</div>';
if ($this->bean->name) {
$this->dv->defs['templateMeta']['form']['buttons'][] = array(
"customCode" => '{$CUSTOMER_PROFILE}'
);
$this->ss->assign('CUSTOMER_PROFILE',
$this->bean->provider->getHostedProfilePageButton($this->bean->name)
);
}
parent::display();
}
}
I have been using Behat for a year or so at a level fine for the automation of most websites but I now need to start using it more for user generated content, I am relatively new to PHP and at the moment I am struggling how to use a String entered in an Example table in an x-path array:
Feature: Campaign
Scenario Outline: Pass campaign string to xpath array
Then I add a new campaign name of "<campaign>"
Examples:
|campaign |
|Automation|
The context file looks like this
/**
* #Then /^I add a new campaign name of "([^"]*)"$/
*/
public function iAddANewCampaignNameOf($campaign)
{
/**
* #var CreateCampaign $createCampaign
*/
$createCampaign= $this->getPage('CreateCampaign');
$createCampaign->campaignName($campaign);
}
Then I use the Page Object extension for the class Campaign.php
class CreateCampaign extends AutomationPage
{
protected $path = 'someURL';
public $campaign;
protected $elements = array(
'campaignHeader' => array('xpath' => "//*[#id='site-navigation-campaigns']"),
);
public function campaignName ($campaign)
{
$this->campaign = $campaign;
$this->getSession()->wait(5000);
$this->getElement('campaignName')->setValue($campaign);
}
So far so good, the tester can enter a campaign name of "Automation" - it gets passed through the context file and the campaign name is set in the browser.
What I am lacking is to be able to retain this $campaign name string and use it in another page so I can reference it in another array i.e. for selecting an existing campaign as follows:
SecondPageObjectPage.php
class ReferenceCampaign extends AutomationPage
{
protected $path = 'someURL';
protected $elements = array(
'referenceCampaign' => array('xpath' => "//*[contains(#id,'***HERE I NEED TO GET THE
$campaign value"),
);
public function editExistingCampaign ($campaign)
{
$this->getElement('referenceCampaign')->click();
}
}
I have tried my best to simplify things and I can explain further if any of this isnt clear - hopefully its just a simple PHP question and not really Behat specific
Thanks Ian
Your example is a much better way of doing things, I have only recently started using partial contains and it expands the flexibility of finding stubborn xpaths especially if you combine more than one, like the working example below:
public function editExistingCampaign ($campaign)
{
$this->getSession()->wait(5000);
$element = $this->find('xpath', '//*[contains(#id,"'.$campaign.'")]
[contains(#id,"actionbuttons")]');
if (isset($element)) {
$element->click();
} else {
throw new Exception('Element not found');
}
}
The only slight change was to add a ] at the end of the x-path
I'm sure it's a simple question, but I think that I am missing a point. If all you want is to get hold of the value that was used on the page then you need to review your code structure. First, you cannot pass method argument to the property definition in another class, but you can find the element inside editExistingCampaign.
class ReferenceCampaign extends AutomationPage
{
protected $path = 'someURL';
public function editExistingCampaign ($campaign)
{
$element = $this->find('xpath', '//*[contains(#id, "' . $campaign . '")]');
if (isset($element)) {
$element->click();
} else {
throw new Exception('Element not found');
}
}
}
I'm assuming you are using Symfony Page Object extension, which you should mention. I'm not sure if I've got the syntax right, but the idea is to find your element inside the method.
I have a PHP script that returns to me my (and my friends) profile pictures, using the following:
http://graph.facebook.com/".$ID."/picture?type=large
where $ID is the ID retrieved using the PHP API. I then use the following for loading the images in my app:
public function LoadProfile()
{
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onUrlLoaded);
loader.load(new URLRequest(ImageURL));
//ImageURL is the URL provided by the PHP Script
// which is the 'http://graph.facebook.com/XXXX/picture?type=large'
}
private function onUrlLoaded(event:Event)
{
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onUrlLoaded);
var path:String = LoaderInfo(event.target).url;
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onReallyComplete);
var lc:LoaderContext = new LoaderContext(true);
lc.checkPolicyFile = true;
loader.load(new URLRequest(path), lc);
}
private function onReallyComplete(event:Event)
{
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onReallyComplete);
}
This works for ALL of my friends, but does NOT work for me for some reason. I get the following general address for the image of my friends:
http://profile.ak.fbcdn.net/hprofile-ak-snc4/370825_524761447_653077984_n.jpg
But for me I just get
http://profile.ak.fbcdn.net
which is some random person ... NOT me ...
I've verified repeatedly that the ID being sent back from the PHP is in-fact my ID, and I've copy/pasted the address traced BEFORE the loading function into a browser and I get my correct profile picture, but somewhere in there it's bugging out for my ID in the load and only my ID in the load (I should rephrase it to say it bugs out for WHATEVER user is logged in to Facebook, not just me).
Any ideas? Or anyone know of an alternative way to get MY profile picture?
public function loadProfile():void
{
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loader_completeHandler);
loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, loader_securityErrorHandler);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loader_ioErrorHandler);
loader.load(new URLRequest(_imageURL));
}
private function loader_securityErrorHandler(event:SecurityErrorEvent):void
{
trace(event.toString());
}
private function loader_ioErrorHandler(event:IOErrorEvent):void
{
trace(event.toString());
}
private function loader_completeHandler(event:Event):void
{
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loader_completeHandler);
loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, loader_securityErrorHandler);
loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, loader_ioErrorHandler);
addChild(loader);
}