How to integrate a symfony website with whmcs - php

I'm trying to find a way to integrate my website, coded using Symfony with my billing system, WHMCS.
The first thing I tried was creating a new symfony module called whmcs and in that module, I was using ob_start/require_once/ob_get_contents to retreive the page but it kept resulting in a blank page, without any error in the logs or anywhere else. Since this was going to be a navigation nightmare anyway, I gave up on that idea.
My second idea was to take advantage of the WHMCS hooks system. So far, it worked except for one thing. I have no idea how to call my layout.php file. Here is my current code:
function getSymfonyLayout()
{
require_once($_SERVER['DOCUMENT_ROOT'].'/../config/ProjectConfiguration.class.php');
$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', true);
$context = sfContext::createInstance($configuration);
$context->getRequest()->setRelativeUrlRoot('');
$context->getInstance()->getConfiguration()->loadHelpers('Partial');
echo get_partial("global/header");
}
add_hook("ClientAreaPage",1,"getSymfonyLayout");
My issue here is that, while the header does load, there is no meta, no css, no javascript. Those settings are saved in my view.yml file and partials don't load that file.
I need to find a way to do something like echo get_layout("layout"); or echo get_methodaction("whmcs", "index");
It's probably something silly but I've been going thru wikis, forums and my symfony book and I just can't find the code I need to use.

Try to use curl
$url = 'your symfony url';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$data = curl_exec($ch);
echo $data;
The code above sends a curl request to the url $url
$query_string is the data you are going to post to the page if needed
$query_string = "";
foreach ($postfields AS $k => $v)
$query_string .= "$k=" . urlencode($v) . "&";
$query_string = trim($query_string, '&');
where $postfields is an array of the parameters to send
Additionally you can send a cross domain ajax request (if you're using jQuery you just set the $.ajax option dataType to jsonp) and that would load only the content part of the action (stylesheets and javascripts are not included)

In your action method, use:
$output = $this->getController()->getPresentationFor("module", "action");
This will render the output of the specified module and action into $output; see http://www.symfony-project.org/api/1_2/sfController#method_getpresentationfor for details

Related

send a pageview event via Measurement Protocol to a GA4 property

How can I send a pageview event via Measurement Protocol to a GA4 property with PHP?
This is how I'm doing, but inside my Google Analytics 4 property I can't see any traffic.
$data = array(
'api_secret' => 'XXXX-YYYYY',
'measurement_id' => 'G-12345678',
'client_id' => gen_uuid(), // generates a random id
'events' => array(
'name' => 'page_view',
'params' => array(),
)
);
$url = 'https://www.google-analytics.com/mp/collect';
$content = http_build_query($data);
$content = utf8_encode($content);
$ch = curl_init();
curl_setopt($ch,CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_HTTPHEADER,array('Content-type: application/x-www-form-urlencoded'));
curl_setopt($ch,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
curl_setopt($ch,CURLOPT_POST, TRUE);
curl_setopt($ch,CURLOPT_POSTFIELDS, $content);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
curl_close($ch);
I'm working on registering pageviews to track API usage right now, here's what I've found:
XTOTHEL is right about setting the content type to content/json above. In addition to specifying the content type you also have to send JSON data as the CURLOPT_POSTFIELDS data.
Also per their specification the api_secret and measurement_id need to be part of the URI: https://developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events?client_type=gtag#required_parameters
Lastly, you can use debug mode to validate your responses and figure out what's going on now by simply changing the URL to google-analytics.com/debug/mp/collect
Here's the code I'm working with right now:
//retrieve or generate GA tracking id
if (empty($_COOKIE['_cid'])) {
setcookie('_cid', vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex(random_bytes(16)), 4)));
}
$data = '{"client_id":"'.$_COOKIE['_cid'].'","events":[{"name":"load_endpoint","params":{"page_location":"'.$request->fullUrl().'"}}]}';
echo '<pre>';
print_r($data);
$measurement_id = 'G-xxxxx';
$api_secret = 'xxxx';
$url = 'https://www.google-analytics.com/debug/mp/collect?api_secret='.$api_secret.'&measurement_id='.$measurement_id;
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
This works to a certain extent. Currently it's registering the page view as a custom event instead of an actual pageview though. I'm still trying to figure out how to get them to come through as page views.
Follow up
After a little more debugging I figured out page views are actually working, they just weren't showing up in some of the views. The fix for that was to add page_title into the params:
$data = '
{
"client_id": "'.$_COOKIE['_cid'].'",
"events": [
{
"name": "page_view",
"params": {
"page_location": "'.$request->fullUrl().'",
"page_title": "'.$request->path().'"
}
}
]
}
';
A few extra notes for whoever comes next:
Debug mode did return some useful validation errors for invalid top-level parameters (client_id, events) - but it didn't return errors for anything inside of the "params" for events. IE - i put "page_asdtitle" instead of "page_title" and it accepted it just fine.
None of the tests I sent through actually showed up in the debug panel while using debug mode. I suspect this is because of the data propagation delay, it's probably not loading realtime data.
Using a JSON validator can help. Make sure you use objects and arrays where GA tells you to.
If you get stuck figuring out why your PHP code doesn't work, write the code as a browser event in JavaScript and run it in your browser. There's tons of examples on how to do that. From there, you can use Dev Tools -> Network to inspect the request. If you right click on the google analytics request to the 'collect' endpoint you'll see an option to Copy Request as CURL. Put that into a text editor and compare it to what your PHP code is sending.
To ACTUALLY test this without the massive propagation delay you can login to Google Analytics, go to Reports -> Realtime, and you should see your data show up within 30-60 seconds if it's working. Realtime data will NOT show up if you're using the /debug/ endpoint though.

Automatically filling out web forms and returning the resulting page

This is my first time posting here. I greatly appreciate any and all guidance on this subject.
I'm trying to make a program that automatically fills in web forms and submits the data, returning the resulting page to the program so it can continue to 'browse' the page, allowing it to recursively submit even more data.
The main problems I'm having are:
The 'submit' button is coded in Javascript, so I don't know where the form data goes when making the page request.
I want to fill in the forms using data from an Excel table, so I need to be able to access data from outside the page.
I need to be able to navigate the resulting page to continue to submit more data.
More specifically, I'm trying to first login to the Practice Mate website, navigate to 'Manage Patients', hit 'Add Patients', and fill in the proper forms and submit.
I'm filling in the forms from an Excel table thousands of rows long.
Sorry I can't be more clear on this without providing a username and password.
What I've been trying to do is use Javascript to make page requests from a page that retrieves information from the Excel document using PHP. I still can't seem to get anything to work with this method though.
I apologize for being a relative novice at this. Thanks in advance.
You can use PHP cURL to browse & submit forms to websites, but it does depend on how the website is setup. Most have security checks in place to prevent bots and can be tricky to get everything to work right.
I spent a little bit of time and came up with this login script. Without a valid username and password I can't verify that it is successful, but should do what you need. This short example first browses to the page to set any cookies and scrape a __VIEWSTATE value needed to submit the form. It then submits the form using the username/password you provide.
<?php
// Login information
$username = 'test';
$password = 'mypass';
$utcoffset = '-6';
$cookiefile = '/writable/directory/for/cookies.txt';
$client = new Client($cookiefile);
// Retrieve page first to store cookies
$page = $client -> get("https://pm.officeally.com/pm/login.aspx");
// scrape __VIEWSTATE value
$start = strpos($page, '__VIEWSTATE" value="') + 20;
$end = strpos($page, '"', $start);
$viewstate = substr($page, $start, $end - $start);
// Do our actual login
$form_data = array(
'__LASTFOCUS' => '',
'__EVENTTARGET' => '',
'__EVENTARGUMENT' => '',
'__VIEWSTATE' => $viewstate,
'hdnUtcOffset' => $utcoffset,
'Login1$UserName' => $username,
'Login1$Password' => $password,
'Login1$LoginButton' => 'Log In'
);
$page = $client -> get("https://pm.officeally.com/pm/login.aspx", $form_data);
// cURL wrapper class
class Login {
private $_cookiefile;
public function __construct($cookiefile) {
if (!is_writable($cookiefile)) {
throw new Exception('Cannot write cookiefile: ' . $cookiefile);
}
$this -> _cookiefile = $cookiefile;
}
public function get($url, $referer = 'http://www.google.com', $data = false) {
// Setup cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_REFERER, $referer);
curl_setopt($ch, CURLOPT_COOKIEFILE, $this -> _cookiefile);
curl_setopt($ch, CURLOPT_COOKIEJAR, $this -> _cookiefile);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
// Is there data to post
if (!empty($data)) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
}
return curl_exec($ch);
}
}
Well, I think the cURL will do the trick, the curl_init() handler is explicable enough. Still at the inception of the doc peruse, howbeit, good results are anticipated. Well, not too sure about the PHP flexibility of structures as that will mean a lot with cURL. Hope to find good luck down the line.

PHP send data to some other webpage

I want to have a script on one website and database on other website.
First website has 2 fields where they enter username and password. Then php posts username/password to other php file and that php does something and then somehow sends the data to my second website, where I insert username and password to MySql database.
So I can do everything except:
I have 2 variables in PHP file, and I want to send them to other webpage, which gets them with maybe $_POST ? Also posting should be automatic, so the script posts them itself not via button press. How to do it?
Is my question clear? I can explain.
Thanks.
Why can't your script on your dummy website retrieve the data via $_POST and then call the script from your real website?
http://davidwalsh.name/execute-http-post-php-curl
Check that out. This way your can POST to your real website from your dummy site's script, completely transparent to the user.
Hope that makes sense.
You can use the PHP cURL library to send these kinds of data requests.
Link: http://php.net/manual/en/book.curl.php
There are three obvious ways to do this:
1) Simple – keep the page hosted on site 2, but use an iframe on site 1 to embed it.
2) Post the form from site 1 to site 2 by setting the action attribute to a script on site 2.
3) Post the form on site 1 to a script on site 1, then use CURL to post it to the other site behind the scenes.
/**
* create request || application/json
* #param $method
* #param $url
* #param $args
* #param $isSentBody
* #param $cert
* #return resource
*/
function createRequest($method, $url, $args, $isSentBody, $cert = false)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
if ($method == 'POST')
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($args));
if ($isSentBody) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($args));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
//'Authorization : Bearer ' . getAccessToken(),
));
}
if ($cert)
curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . $cert);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
try {
return curl_exec($ch);
} catch (Exception $e) {
throw $e;
}
}

To get around the ajax 'same origin policy', code for a PHP ajax request forwarder?

I want to bypass the ajax same-origin policy by having a php page on my site that basically acts like a JSON proxy. Eg i make an ajax request like this:
mysite.com/myproxy.php?url=blah.com/api.json&a=1&b=2
It then makes a request to:
blah.com/api.json?a=1&b=2
And returns the JSON (or whatever) result to the original requester.
Now i assume i'd be stupidly reinventing the wheel if i wrote this php code (plus i don't know php!) - is there some pre-existing code to do this? I'm sure i'm not the only one who's butted my head up against the same-origin policy before.
Oh yeah JSONP isn't an option for this particular api.
Thanks all
Okay, here's something -
Slap this into a php script, call it like this
script.php?url=blah
post the contents you want posted to the server.
<?php
$curlPost = http_build_query($_POST);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $_GET['url']);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = curl_exec($ch);
curl_close($ch);
echo json_encode($data);
?>
Now this script is a bit too open for my liking, so to increase security I would recommend that you add a list of domains to a white list.
So add this to the top:
$whitelist = array('http://www.google.com','http://www.ajax.com');
$list = array();
foreach($whitelist as $w)
$list[] = parse_url($w,PHP_URL_HOST);
$url = $_GET['url'];
$url = pathinfo($url,PHP_URL_HOST);
if(!in_array($url, $list)) die('no access to that domain');

How do you use curl within wordpress plugins?

I'm creating a wordpress plugin and I'm having trouble getting a cURL call to function correctly.
Lets say I have a page www.domain.com/wp-admin/admin.php?page=orders
Within the orders page I have a function that looks to see if a button was clicked and if so it needs to do a cURL call to the same page (www.domain.com/wp-admin/admin.php?page=orders&dosomething=true) to kick off a different function. The reason I'm doing it this way is so I can have this cURL call be async.
I'm not getting any errors, but I'm also not getting any response back. If I change my url to google.com or example.com I will get a response. Is there an authentication issue or something of that nature possibly?
My code looks something like this.. I'm using gets, echos, and not doing async just for the ease of testing.
if(isset($_POST['somebutton']))
{
curlRequest("http://www.domain.com/wp-admin/admin.php?page=orders&dosomething=true");
}
if($_GET['dosomething'] == "true")
{
echo("do something");
exit;
}
function curlRequest($url) {
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
return($response);
}
You're not supposed to use CURL in WordPress Plugins.
Instead use the wp_ function for issuing HTTP requests, e.g.
function wp_plugin_event_handler () {
$url = 'http://your-end-point';
$foo = 'bar';
$post_data = array(
'email' => urlencode($foo));
$result = wp_remote_post( $url, array( 'body' => $post_data ) );
}
add_action("wp_plugin_event", "wp_plugin_event_handler");
In the past I've run into issues where WordPress plugins event handlers would hang with CURL. Using the WP_ functions instead worked as expected.
The admin section of the blog is password-protected, of course. You'll need to pass authentication data. Look up http authentication for details. Look specifically here:
http://www.php.net/manual/en/function.curl-setopt.php
You'll want to set the CURLOPT_USERPWD option and possibly CURLOPT_HTTPAUTH.

Categories