Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

SQL to datamodel problem


Go to End


9 Posts   1217 Views

Avatar
Eirinn

Community Member, 6 Posts

21 December 2014 at 8:48am

Hey guys,

My first post here and while I absolutely love the concept behind silverstripe, the learning curve can be a bit tough.

I have a database that looks like this:
`a_letter_template` (`id`, `name`, `letter`, `stamp`, `paper`)

I have a model file called ComposePage.php where I'm running:
$sqlQuery = new SQLQuery();
$sqlQuery->from = array(
"a_letter_template"
);
$result = $sqlQuery->execute();

The result of a var_dump($result->first()) is:
array(5) {
["id"]=> string(1) "1"
["name"]=> string(8) "Serenity"
["letter"]=> string(20) "/letter/letter-1.png"
["stamp"]=> string(19) "/letter/stamp-1.jpg"
["paper"]=> string(19) "/letter/paper-1.jpg"
}

I need to turn this into a data model set that I can use in ComposePage.ss sort of like this:

<% control letters %>
<% include letter1 %>
<% end_control %>

Letter1 is an ss file which contains basic html and needs data from "a_letter_template", e.g.: $name, $letter, $stamp and $paper.

Resume:
I'm trying to output a letter template for each row in a_letter_template (database) by using silverstripe data object as the content insertion mechanic.

I've tried manually creating a letter class, I've tried ArrayLists, I've tried creating a singleton and everything ends up in server errors.
I could export the assoc as a JSON and parse it through KnockoutJS, but that'd be silly since silverstripe handles server side templating so well.

Avatar
Eirinn

Community Member, 6 Posts

21 December 2014 at 11:38pm

Holy crap spam shoving threads into the oblivion pit.

I know it's Christmas time, but if anyone could help with this problem I'd really appreciate it.

ps: couldn't find a rule about bumping threads.

Avatar
swaiba

Forum Moderator, 1899 Posts

21 December 2014 at 11:39pm

Something like...

$result = $sqlQuery->execute();
$arrayList = new ArrayList();
foreach ($result as $record)
$arrayList->push(new ArrayData($record))

note untested

Avatar
Eirinn

Community Member, 6 Posts

22 December 2014 at 12:25am

Edited: 22/12/2014 12:32am

Thx for the reply!

I slightly rewrote it:
$result = $sqlQuery->execute();
$letters = new ArrayList();
foreach ($result as $record){
$letters->push(new ArrayData($record));
}
As I understand this just creates an array list and not a data set object (unless they're the same)?

If I try to do:

<% control letters %>
<span>$name</span>
<% end_control %>

It just outputs: letters

I find the documentation to be rather odd as it says you need to convert it to an objectDataSet and create a singleton class to handle the procedure.
Which totally makes sense, except that objectDataSet doesn't seem to function from a singleton :S

Maybe I'm confused?

Here's all the code for posterity:

ComposePage.php:

<?php
class ComposePage extends Page {
    // ...
    private static $db = array(
        'ComposeTitle' => 'Text',
        'ComposeSubtitle' => 'Text'
    );
    public function getCMSFields() {
        $fields = parent::getCMSFields();
        $fields->addFieldToTab('Root.Main', new TextField('ComposeTitle'), 'Content');
        $fields->addFieldToTab('Root.Main', new TextField('ComposeSubtitle'), 'Content');
        return $fields;
    }
}

class ComposePage_Controller extends Page_Controller {
}
$sqlQuery = new SQLQuery();
$sqlQuery->from = array(
  "a_letter_template"
);

$result = $sqlQuery->execute();
$letters = new ArrayList();
foreach ($result as $record){
$letters->push(new ArrayData($record));
}
?>

And ComposePage.ss:
<% require themedCSS('base') %>
<% require themedCSS('letter1') %>
<div>
    $ComposeTitle<br />
    $ComposeSubtitle<br />
    $Content
</div>
This is where the compose menu goes when it's done :)

<% control letters %>
<span>$name</span>
<% end_control %>
?>

Which renders into:
To write a new letter, please follow the guide below

This is where the compose menu goes when it's done :) letters

(letters being $name)

Avatar
swaiba

Forum Moderator, 1899 Posts

22 December 2014 at 12:35am

ArrayList and ArrayData are the root of the viewable data that can be returned from controller functions for the template.

DataList (not DataObjectSet - assuming you are using v3) and DataObject are the same as above but extended to actually connect to the Database automatically. If your data is only connected to this system and there is no reason to skip the ORM, then I'd suggest you use DataOBjects and Lists directly.

Avatar
Eirinn

Community Member, 6 Posts

22 December 2014 at 1:05am

It sort of makes sense, but I have no idea how to apply it.

All I want is to convert an assoc sql list into a DataObject and use a loop to display a template using the data from the db. All the references I'm finding are old (>3) and I'm using the newest; Guess that's 3.1 as I downloaded it a few days ago. I've spent 5 hours on the problem and it's pulling teeth out since it seems like it's supposed to be simple. I'm constantly inching a bit closer to the goal only to stumble.

I have a pretty strong (web) developer background, but stuff like this is still new to me.

Avatar
swaiba

Forum Moderator, 1899 Posts

22 December 2014 at 1:18am

It sounds like you might invest time in the lessons first...

http://www.silverstripe.org/learn/lessons/

Avatar
Eirinn

Community Member, 6 Posts

22 December 2014 at 4:59am

Edited: 22/12/2014 5:24am

Thx Swaiba,

I went through all five lessons and made some rather large modifications to my site. The code need to make the compose section however was not covered in any of the five tutorials as I see it. At least not in context.

The problem here is that the letters are to be configured by users of the site. Not site admins or editors. Letter backgrounds are going to be switched around and stamps are custom as well. This is why I've made a separate database that handles letters. If the letters were predefined for the users I could indeed have used the holder/page technique and just have the parent render the children. This is not the case. This is a highly dynamic page.

I would however like to use the silverstripe template rendering engine. That's why I'm pulling data from the db, trying to convert it into data the silverstripe engine can pass onto letter template files. This way I don't have to rely so much on a client side MVC like KnockoutJS and I can hopefully get some caching going.

Does it make sense?

Go to Top