How to use json data from external service in SilverStripe templates? - silverstripe

I want to put data from an extern webservice into my SilverStripe website. I can get the data in an array bij this code:
public function getBlogs(){
$service = new RestfulService("http://www.xxxxx.com/jsonservice/BlogWeb/");
$response = $service->request("getBlogs?token=xxxxx&id=250");
print_r(json_decode($response->getBody()));
}
This shows the right data array in my website. But how can I handle this data to use it in the templates, like:
<% loop getBlogs %>$Title<% end_loop %>
Thanks in advance.

The loop construct is designed to iterate over ArrayLists and DataLists, with each item in that list intended to be a DataObject. Since json_decode returns a PHP array of objects, your function getBlogs() will need to iterate over this array and build an ArrayList of DataObjects that describe each of your blogs.
public function getBlogs() {
$blogs = ArrayList::create();
if($response && $response->getStatusCode() == 200 ) {
$data = json_decode($response->getBody());
foreach($blogs as $blog) {
$b = DataObject::create();
$b->Column1 = $data->blah;
$b->Column2 = $data->bloo;
$blogs->push($b);
}
}
return $blogs;
}
Your <% loop %> construct would then iterate over the ArrayList:
<% loop getBlogs %>
$Me.Column1 is some column. So is $Column2.
<% end_loop %>

Related

return result from function in symfony as global in twig templates

I have a function that returns the number of items in the cart. How it is possible to display this number in every page of the website? I need to show its value in a twig file that is being loaded in all pages of the site...
This is the function I d like to use:
public function getCartCount(){
$session = new Session();
$session_user = $session->get('temp_session_user');
$em = $this->doctrine->getManager();
$details = $em->getRepository('AppBundle:RechargeLogs')->findBy(array(
'sessionVal'=> $session_user,
'status'=> 0
));
There are a lot of solutions for this,
You can create a twig filter:
https://symfony.com/doc/current/templating/twig_extension.html
you can embed controller in twig:
http://symfony.com/doc/current/templating/embedding_controllers.html
you can store a variable in session and access it in twig:
https://symfony.com/doc/current/templating/app_variable.html
you can even create service and register it as a global variable in twig and use it:
https://symfony.com/doc/current/templating/global_variables.html#referencing-services

Output to template, which variable to use?

I have a template which needs to display users that have been assigned to that page via GridField.
When a user is assigned to the page their ID is stored, I am then retrieving that info like so
class Shows_Controller extends Page_Controller {
# Get key people from ShowsContact class / input via ShowsContact GridField
public function getKeyPeople(){
if($this->ShowsContacts()->exists()){
$result = array();
foreach($this->ShowsContacts()->column('MemberID') as $teamMemberID){
array_push($result, Member::get()->byID($teamMemberID)->Nickname);
}
var_dump($result); # Using var_dump here to see if I get what I need...
}
}
}
I have tried using SilverStripes ArrayList but couldn't get that to work either - here's the same thing but using ArrayList...
$result = new ArrayList();
foreach($this->ShowsContacts()->column('MemberID') as $teamMemberID){
$result->add(Member::get()->byID($teamMemberID)->Nickname);
}
var_dump($result);
The output of this is what I'm expecting but I don't understand how to loop through the results and what variable I need to use so that the loop displays the results within my template..?
The result from the var_dump is this, I need to get those names out to the relevant part of the webpage
array(3) {
[0]=>
string(6) "vlad-s"
[1]=>
string(10) "lawrence-r"
[2]=>
string(8) "darren-g"
}
I've also made attempts at using <% with %> but that didn't work either
Edit
Just to mention, I'm only trying to obtain the usernames at the moment but will need to get multiple things from the ID such as Firstname, Surname, ImageURL
Wow finally got it working how I needed it to!
What I was missing was using ArrayData() when trying to add to the ArrayList()
Here's the working code
class Shows_Controller extends Page_Controller {
# Get key people from ShowsContact class // input via ShowsContact GridField
public function getKeyPeople(){
if($this->ShowsContacts()->exists()){
$result = new ArrayList();
foreach($this->ShowsContacts()->column('MemberID') as $teamMemberID){
$result->add(new ArrayData(array(
'Nickname' =>Member::get()->byID($teamMemberID)->Nickname
)
));
}
return $result;
}
}
}
And now in my template I can use
<% loop KeyPeople %>
$Nickname
<% end_loop %>
To get the data out where I need it!

How can I get the format the results of a CheckboxsetField as a comma separated string in SilverStripe?

I'm trying to create some filters for a datalist. I'd like the user to be able to select one or multiple filters from a list of tags and then spit out a list of objects based on those filters. All is good using this code to grab data based on the URL params being sent...
public function index(SS_HTTPRequest $request)
{
// ...
if($tagsParam = $request->getVar('tags')) {
$articles = new ArrayList();
$tagids = explode(",", $tagsParam);
foreach($tagids AS $tagid) {
$tag = Category::get()->byID($tagid);
$articleitems = $tag->getManyManyComponents('Articles')->sort('Date DESC');
foreach($articleitems AS $articleitem) {
$articles->push($articleitem);
}
}
}
$data = array (
'Articles' => $articles
);
if($request->isAjax()) {
return $this->customise($data)->renderWith('ListItems');
}
return $data;
}
That code works fine with a URL like mysite.com/?tags=1,2,3
My issue comes with trying to generate that URL based on the filters built with a CheckboxSetField. Here is my code for that...
public function ArticlesSearchForm()
{
$tagsmap = $this->getTags()->map('ID', 'Title')->toArray();
$form = Form::create(
$this,
'ArticlesSearchForm',
FieldList::create(
CheckboxSetField::create('tags')
->setSource($tagsmap)
),
FieldList::create(
FormAction::create('doArticlesSearch','Search')
)
);
$form->setFormMethod('GET')
->setFormAction($this->Link())
->disableSecurityToken()
->loadDataFrom($this->request->getVars());
return $form;
}
When the user submits that form, the URL generated is something along the lines of mysite.com?tags%5B1%5D=1&tags%5B2%5D=2&action_doArticlesSearch=Search Obviously, it's passing the values as an array. How can I pass a simple comma separated list?
Rather than trying to change the return of CheckboxSetField, I'd recommend changing your code. Given you are converting the comma-separated list list into an array already here:
$tagids = explode(",", $tagsParam);
Something like this, will skip this step:
public function index(SS_HTTPRequest $request)
{
// ...
if($tagsParam = $request->getVar('tags')) {
$articles = new ArrayList();
//This has a minor risk of going bad if $tagsParam is neither an
//array of a comma-separated list
$tagids = is_array($tags) ? $tagsParam : explode(",", $tagsParam);

SS3: the method 'fortemplate' does not exist on 'ArrayList'

In Silverstripe 3, I'm trying to run some custom SQL and return the result for handling in my template:
function getListings(){
$sqlQuery = new SQLQuery();
$sqlQuery->setFrom('ListingCategory_Listings');
$sqlQuery->selectField('*');
$sqlQuery->addLeftJoin('Listing', '"ListingCategory_Listings"."ListingID" = "Listing"."ID"');
$sqlQuery->addLeftJoin('SiteTree_Live', '"Listing"."ID" = "SiteTree_Live"."ID"');
$sqlQuery->addLeftJoin('ListingCategory', '"ListingCategory_Listings"."ListingCategoryID" = "ListingCategory"."ID"');
$sqlQuery->addLeftJoin('File', '"ListingCategory"."IconID" = "File"."ID"');
$result = $sqlQuery->execute();
$dataObject = new ArrayList();
foreach($result as $row) {
$dataObject->push(new ArrayData($row));
}
return $dataObject;
}
However, this is giving me the error:
Uncaught Exception: Object->__call(): the method 'fortemplate' does
not exist on 'ArrayList'
What am I doing wrong here and how can I get the result of this query into my template?
I have not seen your template code, but I am assuming you are just calling $Listings in template.
Which will not work because ArrayList has no forTemplate method (what forTemplate does is output the object as a appropriate string, for example a forTemplate on Form outputs a html element).
You probably want to do is loop the List and use the object:
<% loop Listings %>
$ID
$Something
$Foobar
<% end_loop %>
or, you can call forTemplate on the object if it has that method:
<% loop Listings %>
$forTemplate
<% end_loop %>

Dataobject in Silverstripe: Getting data from a Wordpress database

Apologies if this is a simple one, I'm getting my head round how data objects work in Silverstripe.
My task is to obtain a list of posts from a wordpress blog (currently on /blog) on our site, and display the most recent post in the footer, and in another case, display posts by certain editors on their page.
I've seen the manual page for SqlQuery, but whenever I try anything from it I get an error. The code I'm using is based on the example, and looks like this:
$sqlQuery = new SQLQuery();
$sqlQuery->select = array(
'post_title',
'post_content',
'post_name'
);
$sqlQuery->from = array("
wp_posts
");
$sqlQuery->where = array("
post_status = 'publish'
");
$sqlQuery->orderby = "
post_date DESC
";
// $sqlQuery->groupby = "";
// $sqlQuery->having = "";
// $sqlQuery->limit = "";
// $sqlQuery->distinct = true;
// get the raw SQL
$rawSQL = $sqlQuery->sql();
// execute and return a Query-object
$result = $sqlQuery->execute();
$myDataObjectSet = singleton('wp_posts')->buildDataObjectSet($result);
var_dump($myDataObjectSet->First()); // DataObject
The error I'm getting is:
[User Error] Bad class to singleton() - wp_posts
This will return you a DataObjectSet of your WordPress posts (latest 3 in this case). Assuming WordPress resides in the same database as SilverStripe.
function LatestPosts() {
$sqlQuery = new SQLQuery();
$sqlQuery->select("post_title", "post_content");
$sqlQuery->from("wp_posts");
$sqlQuery->where("post_status = 'publish'");
$sqlQuery->orderby("post_date DESC");
$sqlQuery->limit(3);
if ($result = $sqlQuery->execute()) {
$wp_posts = new DataObjectSet();
foreach($result as $row) {
$wp_posts->push(new ArrayData($row));
}
return $wp_posts;
}
return;
}
You can then iterate over your DataObjectSet in your template.
<% if LatestPosts %>
<% control LatestPosts %>
<h3>$post_title</h3>
<div>$post_content</div>
<% end_control %>
<% end_if %>

Resources