Unable to upload files in SilverStripe 4 - php

I've created a simple extension to SiteConfig to add a logo uploadfield to the settings section. However, the server returns an error upon uploading a file.
SiteConfig.php
namespace mymodule\siteconfig;
use SilverStripe\ORM\DataExtension;
use SilverStripe\Forms\FieldList;
use SilverStripe\AssetAdmin\Forms\UploadField;
class SiteConfig extends DataExtension {
private static $has_one = array(
'Logo' => 'SilverStripe\\Assets\\File'
);
public function updateCMSFields(FieldList $fields) {
$fields->addFieldToTab('Root.Main', $logo = UploadField::create('Logo', 'Logo upload'));
}
}
Server's error log does not show anything relevant to this error. Whats going on here?
UPDATE
I just tried to upload a file to the Files section in the CMS, got the exact same error.

private static $has_one = [
'LogoImage' => Image::class,
];
public function updateCMSFields(FieldList $fields) {
$fields->addFieldToTab('Root.Main', UploadField::create('LogoImage', 'Logo'));
}

Related

How to automaticly publish images in silverstripe dataextension

I was trying to add an uploadfield to a Custom DataExtension and got the Image field working. However the image i uploaded stays in concept mode, and i have to go to the File tab to publish it. I tried to use the code provided in the Silverstripe documentation but this only seems to work on regular pages. I found a question similar to mine:How to automaticaly publish files uploaded to a dataobject in Silverstripe model admin however this only seems to work on DataObjects.
This is my current code:
<?php
use SilverStripe\Forms\LiteralField;
use SilverStripe\Forms\TextField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\HTMLEditor\HTMLEditorField;
use SilverStripe\AssetAdmin\Forms\UploadField;
use SilverStripe\Assets\Image;
use SilverStripe\Assets\Storage\AssetStore;
use SilverStripe\Versioned\Versioned;
use SilverStripe\ORM\DataExtension;
class CustomSiteConfig extends DataExtension
{
private static $db = [
];
private static $has_one = [
'Logo' => Image::class
];
private static $owns = [
'Logo'
];
private static $extensions = [
Versioned::class,
];
private static $versioned_gridfield_extensions = true;
public function updateCMSFields(FieldList $fields)
{
$fields->addFieldToTab("Root.Header", LiteralField::create("","<h1>Header</h1>"));
$fields->addFieldToTab("Root.Header", UploadField::create('Logo', 'Logo'));
}
}
Does anyone know a solution?
There's currently a bug that prevents "owned" records to be published if the owning dataobject is not versioned.
I think you're experience this bug, since SiteConfig is not versioned and thus won't publish owned files/images when it's being saved.
Until this bug has been resolved, you could use an onAfterWrite hook in your extension to publish the file:
public function onAfterWrite()
{
if ($this->owner->LogoID) {
$this->owner->Logo()->publishSingle();
}
}

What is the best prestashop-way to include tpl in AdminController?

I need interacts with a .tpl file in my adminController class, but when I try to do that, this error appears
Fatal error: Call to undefined method RiddlePageController::getCacheId() in /home/USER/public_html/prestashop/modules/RiddleModule/controllers/admin/RiddlePage.php on line 48
This is my admin controller code:
class RiddlePageController extends AdminController {
public function __construct()
{
$this->html = '';
$this->display = 'view';
$this->meta_title = $this->l('metatitle');
$this->module = "RiddleModule";
parent::__construct();
}
public function initContent()
{
$this->postProcess();
$this->show_toolbar = true;
$this->display = 'view';
$this->meta_title = $this->l('Modulo');
parent::initContent();
}
public function initToolBarTitle()
{
$this->toolbar_title = $this->l('Titulo');
}
public function initToolBar()
{
return true;
}
public function renderView() {
$this->context->smarty->assign(
array(
'img1' => "http://www.free-3dmodels.com/image/Flowers-3D-Model-3662994d.png",
'img2' => "http://www.all3dmodel.com/Images/39.jpg"
)
);
// in return have error "getCacheId"
return $this->display(__FILE__, 'content.tpl', $this->getCacheId());
// return "<b>This works fine!!</b>";
}
my tpl file have only {$img1} and {$img2} for testing.
Maybe I do all wrong, and this is not the best way to make in my own admin page.
Your error is because the AdminController class doesn't have the getCacheId method.
To answer to your question you have to made some little fix.
First (extends ModuleAdminController not AdminController):
class AdminRiddlePageController extends ModuleAdminController
{
}
Then if you want to view your custom tpl, place a view.tpl file in:
prestashop/modules/RiddleModule/views/templates/admin/riddlepage/helpers/view/
or
prestashop/modules/RiddleModule/views/templates/admin/riddle_page/helpers/view/ (I don't remember well if the underscore is necessary)
And your renderView method should be like this:
public function renderView()
{
/* Your code */
/* Use this snippet to assign vars to smarty */
$this->tpl_view_vars = array(
'myvar' => 1,
'secondvar' => true
)
return parent::renderView();
}
AdminController class has not an implementation of display method you use to render TPL.
You can use something like this after set module var:
$this->module->display(_PS_MODULE_DIR_.$this->module->name.DIRECTORY_SEPARATOR.$this->module->name.'.php', 'content.tpl')
Good luck.
As #TheDrot told us, the answer are in using $this->context->smarty->fetch(location), but not in renderList, but in the return statement of renderView is OK and prestashop get the tpl file and load correctly the smarty variables. Ex:
public function renderView(){
$this->context->smarty->assign(
array(
'img1' => "http://www.free-3dmodels.com/image/Flowers-3D-Model-3662994d.png",
'img2' => "http://www.all3dmodel.com/Images/39.jpg"
)
);
return $this->context->smarty->fetch(_PS_MODULE_DIR_ . "RiddleModule/controllers/front/prueba.tpl");
}
The file location isn't important to load the TPL file in this case

Adding a form action to a config page

I've been trying to make an extension to add some function to the CMS. As it's a setting for the CMS I've added it to the settings tab. While I can take values and save them I needed an action on the page to synchronise a system and I can't get my action to be called, here is my code.
private static $db = array(
'Path' => 'Varchar(50)',
);
private static $allowed_actions = array (
'update',
);
public function updateCMSFields(FieldList $fields)
{
$fields->addFieldsToTab('Root.Importer', array(
ImporterPathField::create('Path', 'Path')->setDescription('Path to area'),
FormAction::create('update', 'Synchronise')
));
}
public function update() {
SS_Log::add_writer(new SS_LogEmailWriter('test#example.com'), SS_Log::ERR);
}
It doesn't get called. If I need to add the function to the left nav rather than part of the settings I'm ok with that too but I also tried that with even less success. Is it possible to get the action called on button press?
You need to place the $allowed_actions and the update method in an extension for CMSSettingsController. Also you should probably put the FormAction into the CMSActions list.
Here's how I would do this:
SiteConfigExtension.php
class SiteConfigExtension extends DataExtension
{
private static $db = array(
'Path' => 'Varchar(50)',
);
public function updateCMSFields(FieldList $fields)
{
$fields->addFieldsToTab('Root.Importer', array(
ImporterPathField::create('Path', 'Path')->setDescription('Path to area')
));
}
public function updateCMSActions(FieldList $actions)
{
$actions->push(
FormAction::create('update', 'Synchronise')
);
}
}
CMSSettingsControllerExtension.php
class CMSSettingsControllerExtension extends DataExtension
{
private static $allowed_actions = array (
'update',
);
public function update() {
SS_Log::add_writer(new SS_LogEmailWriter('test#example.com'), SS_Log::ERR);
}
}

Extending File: can't add field to Root.Main

I want to add a Tag field to all Files in a SilverStripe 3.3.1 site. I'm using Blog v2.4.0 and have upgraded tagfield to v1.2.1.
My FileExtension is configured to extend File:
class FileExtension extends DataExtension
{
private static $many_many = ['FileTags' => 'FileTag'];
public function updateCMSFields(FieldList $fields)
{
$tagField = TagField::create('FileTags', 'Tags', FileTag::get(), $this->owner->FileTags())
->setShouldLazyLoad(true)
->setCanCreate(true);
$fields->push($tagField);
}
}
The FileTag class is:
class FileTag extends DataObject
{
private static $db = ['Title' => 'Varchar(255)'];
private static $belongs_many_many = ['Files' => 'File'];
}
The extension hook I'm attaching to is here, and it provides a standard FieldList as described in the extension documentation.
The problem!
The field shows up correctly, but it's outside of the Root.Main tab and looks like this:
I've tried:
Using addFieldToTab('Root.Main', $field) - it results in [User Error] FieldList::addFieldToTab() Tried to add a tab to object 'FieldList' - 'Root' didn't exist.
As above, using Root and Main
Why doesn't this work the way it is supposed to?
The problem is Folder is a type of file, but Folder does not have a Root.Main tab in its CMS FieldList.
When adding fields to File we need to check that the File type is not Folder:
class FileExtension extends DataExtension {
public function updateCMSFields(FieldList $fields) {
if (!$this->owner instanceof Folder) {
$tagField = TagField::create('FileTags', 'Tags', FileTag::get(), $this->owner->FileTags())
->setShouldLazyLoad(true)
->setCanCreate(true);
$fields->addFieldToTab('Root.Main', $tagField);
}
}
}

How to add extra summary_field in Silverstripe when extending an object?

I'm wanting to extend an existing Silverstripe module (Swipestripe) where Attribute has_many Options.
The following code successfully extends Option so a Cost is added to each Option.
class OptionCost extends DataExtension {
private static $db = array(
'Cost' => 'Decimal(19,4)'
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Main', new PriceField('Cost'));
return $fields;
}
}
However when viewing the options via the parent Attribute the Cost is not display. This is controlled via the $summary_fields static but I can't work how to add Cost as a new summary field.
I've tried adding the following code to OptionCost, and to an extension of Attribute - but neither method worked.
private static $summary_fields = array(
'Cost' => 'Cost'
);
What is the correct approach to add Cost to the summary_fields table?
Thank you in advance for any advice.
In Silverstripe 3.1 adding fields to $summary_fields in the extension is the correct way to do this.
The following code worked for me:
class OptionCost extends DataExtension {
private static $db = array(
'Cost' => 'Decimal(19,4)'
);
private static $summary_fields = array(
'Cost'
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Main', new PriceField('Cost'));
return $fields;
}
}
Declare the extension in your config or in a config yaml file.
config.yml
...
Attribute:
extensions:
- OptionCost
...
Run a dev/build?flush=all.
Also make sure you call ?flush=all on your admin page.

Categories