WHMCS Addon Module with Multiple Pages - api

I am currently working on developing my first WHMCS Addon Module, and so far everything has gone very well. However, I need to make multiple content pages, and the only way to display output according to the Wiki Article is to echo it in the output function. How can I create individual pages when the only way to display content is via a single PHP function?
I am assuming using divs, and hiding the relevant divs, although not exactly the best method. It says you can use the "modulelink" variable to link back to the module, but I have no idea how to use this, or if it can be used for making multiple content pages.
http://docs.whmcs.com/Addon_Module_Developer_Docs

After some tinkering, it was much more simple than I realized, and the "modulelink" variable was just so you could link back to the page. To create additional pages, you can basically just do something along the lines of...
Datacenters
Then in the output function have...
$category = $_GET['catid'];
if ($category == "1" || $category == "")
{
//page 1 content here
}
else if ($category == "2")
{
//page 2 content here
}
and so on.

Related

PageNumber in Scripts for ActiveReports 7

I'm not very used to Active Reports and I got an old software using those. The software provide some kind of stripped version of Active Reports Designer 7.
I got a PageFooter section with some fields and I want to remove one to display it only when it's the last page.
Basically, what I want to do is this in scripts :
if (this.PageNumber == this.PageCount) {
Field.Visible = true;
}
I only find one post here that say this.PageNumber should work, but it dosent.
So I tried to use the ReportInfo using the FormatString as {PageNumber}, but I don't seems to be able to read the value using this.ReportInfo.Value or this.ReportInfo.Text
I also tried to make a TextBox, using SummaryType : PageCount. But I'm still unable to read the Value.
So the question is :
How can I know the Page Number and Page Count in the script section?
Or how can I read the value of those textbox I created ?
Thanks a lot!
I think these docs cover what you are looking for:
https://help.grapecity.com/activereports/webhelp/Legacy/AR7Help/OnlineEN/AddPageNumbering.html
https://help.grapecity.com/activereports/webhelp/Legacy/AR7Help/OnlineEN/index.html

Carry get parameter to checkout in Shopify

If a customer lands on any page of the Shopify site (not Plus), with a referral parameter in GET (?ref=something), how can this value be carried over to the checkout and order confirmation pages, where the domain is different?
One idea I had was to set a cookie on our domain, and then modify URL one navigates to upon clicking Checkout to include the values of the cookies, but I am unsure if this is the cleanest way, and where the best place to modify the URL would be.
I see that _ga parameter appears to be included automatically, in checkout URL. How can this be done for custom GET parameters?
One is the tricky way for doing this by modifying the checkout URL before submitting.
For doing this on your cart.liquid file find the form with action="/cart" and add attribute:
onsubmit="update_action(this)"
And add the javascript code at the bottom of your theme.liquid file :
<script type="text/javascript">
function update_action(form){
var new_action;
var some_value = "something";
var form_action = form.action;
if( (form_action.indexOf("?") >= 0) ) {
if(form_action.indexOf("ref")>=0) {
new_action = form_action.replaceAt(form_action.indexOf("ref"),"ref="+some_value);
}else{
new_action = form_action+"&ref="+some_value;
}
}else{
new_action = form_action+"?ref="+some_value;
}
$(form).attr("action",new_action);
}
</script>
Hope this will solve your problem.
Note that the ref and landing page are automatically stored by Shopify, meaning without you doing anything, you get those values in the order placed by the customer. You do not have manually manipulate them as per this thread.
Why do you need the value on checkout (you can do nothing with it anyway) and why on the order confirmation where again, it serves no purpose for the customer?

How to rewrite rules NginX in this example?

I am creating an API to feed some apps.
So the app could call these possible URLs to get information from the database;
mysite.com/api/v1/get/menus/list_tblname1.json.php
mysite.com/api/v1/get/menus/list_tblname1.json.php?type=arr
mysite.com/api/v1/get/menus/list_tblname2.json.php
mysite.com/api/v1/get/menus/list_tblname2.json.php?type=arr
In php I have already the code that grabs the tblname from the URL and give me back all the table content. It works good (it is not the final version).
But now I find myself copying and pasting the same code for each page where the URL points to. Here is the code:
<?php
header('Content-Type:application/json');
include_once '../../../../class/db.php';
$verb=$_SERVER['REQUEST_METHOD'];
$filePath=$_SERVER['SCRIPT_NAME'];
$split1 = explode("/", $filePath);
preg_match("/(?<=_)[^.]+/", $split1[5], $matches);
$tableName = $matches[0];
if ($verb=="GET") {
header("HTTP/1.1 200 ok");
if(isset($_GET['type']) && $_GET['type']=="arr"){
echo db::get_list($tableName,'arr');//Reply ARRAY
}
else{
echo db::get_list($tableName);//Reply JSON
}
}
else{
die("Nothing for you at this page!");
}
I mean, I have the same code inside each these pages.
list_tblname1.json.php
list_tblname2.json.php
I am not sure how to solve this situation but I think that this is case for
rewrite rules.
So, I think a possible solution is to create one page that could call
returncontent.php for example and create rules in the server that should point to the same page when certanlly pages are requested and pass the parameter $tableName to the page. I think I should pass the regex to my server and grab the $tableName with $_GET[] (I think) inside returncontent.php.
I am not sure about it.
I am using NginX.
How to implement it in this scenario?
As a rule, it's bad practice to parse a URI in NginX and pass the result downstream.
Rather: mysite.com/api/v1/get/menus/returncontent.php?file=list_tblname2.json
No changes to NginX needed. Parse the query param (file) in PHP.

How do I pull in page's "url path" field, via php, into the theme?

I'm trying to apply the page's url as a <div> id to be able to target some css on each individual page. After some characters cleanup I'm hoping to get <div id="test-page">.
I have tried pulling it in from the object that I get via
ipContent()->getBreadcrumb()
Unfortunately they are all (including one I need) protected and cannot be echoed out.
[urlPath:protected] => test-page/
Is there a function that I've missed and can use to pull that in? Or a proper method of getting it from the object? Cheers.
And of course, as soon as I posted a question I've found the answer:
I could not get the protected value from [urlPath:protected] => test-page/ when doing this:
$a = ipContent()->getBreadcrumb();
$a = $a[0];
$a = $a->urlPath;
Solution: The way you can pull this is is by replacing $a->urlPath with $a->getUrlPath().
It will work for all the elements in object. Like: $a->updatedAt; needs to be $a->getUpdatedAt();

Implementing Google Custom Search with filtering

I have to implement a page with multiple google-powered search forms. We have a license from Google for CSE, and this is the situation:
I have a search form that's present at the top of every page that performs a simple search and displays the results in a separate page. This works.
I have a particular page that, in addition, shows another two search forms: one should filter articles by category, another should filter articles by category and restrict the result to a certain month. I have added a meta key with the publication date to each article for this.
I have gotten a bit lost in the documentation, though: if I add
<gcse:searchbox-only resultsUrl="/[site]/stat/search/google_search_results.html"></gcse:searchbox-only></div>
to the page, I can't filter the results. If I start to meddle with a CustomSearchObject, I don't see an option to show results on a different page.
For category-based filtering, I've tried appending
more:pagemap:metatags-taxonomies:news
to the query argument in the results page URL, and it does work, but I don't understand how to inject this to the form.
For restricting based on dates, I tried adding
&sort=more:pagemap:metatags-pubdate:r:YYYYMMDD:YYYYMMDD
but haven't been able to make it work. Getting the XML does work:
http://www.google.com/search?q=intitle:[mysite]%20more:pagemap:metatags-taxonomies:News&sort=metatags-pubdate:r:20120401:20120830&cx=[mykey]client=google-csbe&output=xml
returns correct results.
Is there documentation that doesn't assume so much? All I find are code snippets without context. I've checked Filtering and sorting, Custom Search Element Control API, and of course this site, but I can't put all the pieces together.
I managed to implement what I wanted. In the search page, I built simple forms pointing to my results pages (this might not be doable if you must implement google branding), and in the results page I put the following:
(in the <head>)
<script src="http://www.google.com/jsapi"></script>
<script>
// This function extracts the query from the URL (if GET) or builds a search query.
// Code removed to simplify the example.
function buildQuery () {
return '<?php echo $_POST['q'];?> more:pagemap:metatags-taxonomias:News'); // injecting the taxonomy metatag filter
}
google.load('search', '1', {language : 'es'});
google.setOnLoadCallback(function() {
var customSearchOptions = {};
customSearchOptions[google.search.Search.RESTRICT_EXTENDED_ARGS] = {'sort':'metatags-pubdate:d,metatags-pubdate:r:<?php echo $_POST['startdate'];?>:<?php echo $_POST['enddate'];?>'}; // these come from the POST request, are processed earlier in the script.
var customSearchControl = new google.search.CustomSearchControl('XXXXXXXXXXX', customSearchOptions); // Put your own App key here.
customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET);
var drawOptions = new google.search.DrawOptions();
drawOptions.enableSearchResultsOnly(); // I don't want the search box here
customSearchControl.draw('cse-results-press', drawOptions);
var query = parseQuery();
if (query) {
customSearchControl.execute(query);
}
}, true);
</script>
In the <body>:
<div id="cse-results-press">Loading...</div>