SSbits - Home page
site by aabweb
Submit a Post >

Tutorials - Big bits of code to help you do more

Creating and deleting dataobjects from the front end

postproposal3

One of my clients wanted a clear interface from which he could easily attach downloadable files to some pages of his site. Instead of using modelAdmin and granting him an access to Silverstripe admin panel, I chose to create a front-end page showing a simple upload form, a list of the files previously uploaded to the server, and a delete button for each of them.

First steps

Creating the "Programme" page the uploaded files will be attached to, and the "Telechargement" dataobject for the uploaded file

mysite/code/Programme.php

Each "programme" can have many "telechargements" :

<?php

class Programme extends Page {

	public static $has_many = array(
		'Telechargements'=>'Telechargement'
		);
	
	}

mysite/code/Telechargement.php

Each "telechargement" can be attached to only one "programme" :

<?php

class Telechargement extends DataObject {
	
	public static $db = array(
		'Title'=>'Text'
		);

	static $has_one = array(
		'MonProgramme' => 'Programme',
		'Fichier' => 'File',
		'MaPageTelechargement' => 'PageTelechargement'
		);
	
	}

themes/blackcandy/templates/Layout/Programme.ss

Shows a list of the downloadable files :

<h1>$Title</h1>

$Content

<% if Telechargements %>

	<p>Downloadable files :</p>
	
	<ul>
	<% control Telechargements %>
		<li><a href="<% control Fichier %>$Link<% end_control %>" target="_blank">$Title</a></li>
	<% end_control %>
	</ul>

<% end_if %>

Second step

Creating the "PageTelechargement" page for the upload form

mysite/code/PageTelechargement.php

<?php

class PageTelechargement extends Page {
	
	public static $has_many = array(
		'Telechargements' => 'Telechargement'
		);
	
	}
	
class PageTelechargement_Controller extends Page_Controller {

	public static $allowed_actions = array (
	'UploadForm'
	);

	function UploadForm() {
		
		// retrieve all the "Programme" pages
		$myDoSet = DataObject::get("Programme","","Title ASC");
		if($myDoSet){$map = $myDoSet->toDropDownMap();}

		// form fields			
		$fields = new FieldSet(
			new TextField('Title', 'File name :'),
			new FileField('Fichier', 'Upload file :','','','','telechargements' ),
			// The user can tick a radio button to choose the programme related to the uploaded file
			new OptionsetField('MonProgrammeID','Related programme :', $map),
			);
			
		$actions = new FieldSet(    
			new FormAction('UploadFiles', 'Télécharger')
			);
	 
		// all fields are required
		$validator = new RequiredFields('Title', 'Fichier', 'MonProgrammeID');
		
		// return form
		$form = new Form($this, 'UploadForm', $fields, $actions, $validator);			
		return $form;
		
		}

	// write a new "Telechargement" dataobject into the database
	function UploadFiles($data, $form) {
		$transfert = new Telechargement();
		$form->saveInto($transfert);
		$transfert->write();
		Director::redirectBack();

		}
	}

themes/blackcandy/templates/Layout/PageTelechargement.ss

Our template so far :

<h1>$Title</h1>
$Content
$UploadForm

Third step

Probably the most interesting part, which involves rules and actions : creating a function to delete a "Telechargement" dataobject previously created

mysite/code/PageTelechargement.php

<?php

class PageTelechargement extends Page {
		
	...
	
	}
	
class PageTelechargement_Controller extends Page_Controller {

	public static $allowed_actions = array (
	'UploadForm',
	// allow a new action
	'delete'
	);

	function UploadForm() {
		...
		}

	function UploadFiles($data, $form) {
		...
		}
	
	// create our delete function
	function delete(){
		// get the ID parameter in the URL
		$Params = $this->getURLParams();
		// get the dataobject corresponding to the ID
		if ($downloadToDelete = DataObject::get_by_id('Telechargement', (int)$Params['ID']))
		// delete the dataobject found and go back to the page
		{$downloadToDelete->delete();}
		Director::redirectBack();
		}
		
	}

mysite/_config.php
We now need to write our rule. URLs ending with ".../delete/ID" will be handled by the "PageTelechargement" controller and the delete function will be called :

mysite/_config.php

We now need to write our rule. URLs ending with ".../delete/ID" will be handled by the "PageTelechargement" controller and the delete function will be called :

Director::addRules(100, array(
	'delete//$ID!' => 'PageTelechargement_Controller'
));

themes/blackcandy/templates/Layout/PageTelechargement.ss

That's it. Now, we can create a list showing the uploaded dataobjects in the template and add a link to delete each of them :

<h1>$Title</h1>
$Content

<ul>
<% control Telechargements %>
<li>
Name : $Title -
File : <% control Fichier %><a href="$Link">$Name</a><% end_control %> -
Programme : <% control MonProgramme %><a href="$Link">$Title</a><% end_control %> -
<a href="{$Top.Link}delete/$ID" title="">delete ?</a>
</li>
<% end_control %>	
</ul>
	
$UploadForm

A simplified ComplexTableField for the front end !

  • swaiba
    03/07/2012 2:43pm (11 months ago)

    Hi, Great article - I just wonder whether someone might have shown you https://github.com/chillu/silverstripe-genericviews

  • stallain
    03/07/2012 3:13pm (11 months ago)

    @ Swaiba - Thank you
    I didn't know about this module before. It would probably have saved me time !

  • Bart van Irsel
    03/07/2012 8:07pm (11 months ago)

    Hi stallain, great article which explains the basic concepts of building a frontend editor of data-objects, thanks! I guess you limit access to this page in the CMS, so for example the delete method of the controller is not available for users which are not logged in.

  • stallain
    04/10/2012 10:49pm (8 months ago)

    @Lobek
    Hi, I think you simply have to change this in the "delete" function :
    $downloadToDelete->Image()->delete();
    Stan

  • maksfeltrin
    06/11/2012 12:26am (7 months ago)

    Why using Director::addRules instead of PageTelechargement_Controller::url_handlers ?

  • stallain
    06/11/2012 2:58am (7 months ago)

    Hi, my method is to be used with SS 2.4.
    But you're right : since SS3, it seems that you've got to use url_handlers or the routes.yml file instead.

  • Madan Sapkota
    20/11/2012 10:40am (6 months ago)

    Lol this all is fine. After I copy / Paste the code, what should I type in URL? http://example.com/programme or http://example.com/elechargement? both URL i tried an not working. Hope you all can help.

  • stallain
    20/11/2012 11:16am (6 months ago)

    @Madan
    Simply go to the URL of the "PageTelechargement" you created in the CMS

  • Madan Sapkota
    20/11/2012 2:05pm (6 months ago)

    so you mean http://example.com/PageTelechargement? I am very confused in URL routing of SS can you paste me good reference if available.

  • stallain
    20/11/2012 2:19pm (6 months ago)

    http://doc.silverstripe.org/framework/en/ is a good start

  • Madan Sapkota
    20/11/2012 3:20pm (6 months ago)

    @Stallain I knew this URL. What I am asking is the specific reference to the URL I am also confused passing data from controller to Views (.ss files).

  • stallain
    20/11/2012 3:36pm (6 months ago)

    @Madan

    If you use the full package (with cms), you simply have to create a new page in the site tree being of type "PageTelechargement" => you can define its URL through the admin

    If you use only the framework (since SS3), you will have to add routes and define which controller has to be called with the URL of your choice (http://doc.silverstripe.com/framework/en/reference/director). If your controller's name is "MyController", just call your template "MyController.ss", and it should work (see http://doc.silverstripe.org/framework/en/reference/templates#calling-templates-from-php-code).

    Be careful if you use SS3 : the templating language has changed a little (<% loop %> instead of <% control %>, etc.)

  • Madan Sapkota
    20/11/2012 4:08pm (6 months ago)

    :) thank you for the good information and links.

Post a comment ...

You cannot post comments until you have logged in. Login Here.

Advertisement

Site of the Month

Find SSbits on

Top Contributers

Rank Avatar Name
1 article image Aram Balakjian
2 article image Daniel Hensby
3 article image Marcus Dalgren
4 article image Hamish Campbell
5 article image Ty Barho
6 article image Martijn van Nieuwenhoven
7 article image Darren-Lee
8 article image Roman Schmid
9 article image dalesaurus
10 article image Matt Clegg

View full leaderboard


Advertisement