UploadField for Files in SilverStripe - file-upload

I want to insert a new field, below the content textarea, to hold a link/connection to one file (moastly a zip file from my assets folder).
I couldn't find any documentation nor a tutorial for files. Only images. Does anybody know where I can find some help files or can give me some basic code to start from?

In general, there's the API Docs for UploadField.
As well as the docs,
although they're a bit hidden - I'm just fixing the search on doc.silverstripe.org.
This should do the trick:
<?php
class Page extends SiteTree {
static $has_one = array('MyFile', 'File');
function getCMSFields() {
$fields = parent::getCMSFields();
$upload = new UploadField('MyFile');
$upload->setConfig('allowedMaxFileNumber', 1);
$upload->getValidator()->setAllowedExtensions(array('zip'));
$fields->addFieldToTab('Root.Main', $upload);
return $fields;
}
}

Related

symfony 4 Upload

How to upload a file in symfony 4.I have done with the symfony document. I don't know where I have missed something. Its throws error while uploading file give me some clues
REFERED LINK:
https://symfony.com/doc/current/controller/upload_file.html
ERROR:
The file "" does not exist
Entity
public function getBrochure()
{
return $this->brochure;
}
public function setBrochure($brochure)
{
$this->brochure = $brochure;
return $this;
}
File upload Listener
class FileUploader
{
private $targetDirectory;
public function __construct($targetDirectory)
{
$this->targetDirectory = $targetDirectory;
}
public function upload(UploadedFile $file)
{
$fileName = md5(uniqid()).'.'.$file->guessExtension();
$file->move($this->getTargetDirectory(), $fileName);
return $fileName;
}
public function getTargetDirectory()
{
return $this->targetDirectory;
}
}
This Symfony tutorial works fine for me so I'll try to explain how and perhaps it will help you or people still looking for an answer, this post getting a bit old.
So first you have to create the FileUploader service in App\Service for better reusability (chapter: Creating an Uploader Service). You can basically copy/paste what they've done here, it works like a charm. Then you need to open your services.yaml in Config folder and explicit your brochure directory:
parameters:
brochures_directory: '%kernel.project_dir%/public/uploads/brochures'
# ...
services:
# ...
App\Service\FileUploader:
arguments:
$targetDirectory: '%brochures_directory%'
Now everything is normally ready to use your FileUploader service.
So if you're in your controller (for example), I guess you want to use it in a form. Thus, you just have to do this (don't forget to use your Service in your Controller):
public function myController(FileUploader $fileUploader)
{
// Create your form and handle it
if ($form isValid() && &form isSubmitted()) {
$file = $myEntity->getBrochure();
$fileName = $this->fileUploader->upload($file);
$myEntity->setBrochure($fileName);
// Form validation and redirection
}
// Render your template
}
One important point I forgot to say. In your FormType, you need to say that the Brochure will be a FileType:
$builder->add('brochure', FileType::class)
But in your entity you have to specify your brochure is stored as a "string":
/**
* #MongoDB\Field(type="string")
*/
protected $brochure;
The reason is your file is getting uploaded and saved in your public/uploads/brochure. But your database is only remembering a string path to reach it.
I hope this will help!

What is module's "themes" folder used for?

PS documentation says that when developing a module you can create the /themes/[theme_name]/modules subfolder and that it is used for:
"Sub-folder for overriding .tpl files and languages files, if necessary."
and that it:
"enables you to handle the module's template files in various ways, depending on the current theme.",
but i don't really understand its practical usage. What would be a use case of it?
Thanks
When you develop a Prestashop website you should never change core files. This mean that you can only create new modules in the /modules/ folder but not alter existing one. Because if you update a module you altered, all your changes will be gone.
Each time Prestashop needs to load a module template file it will first look in the current theme /themes/your_theme/modules/the_module/path_to_tpl.tpl if an override of this template exists. If not it will load the template from the /modules directory.
This recommandation is also valid for .css and .js files.
The documentation you mentioned in the comment below is wrong and should be updated. You can't put a themes folder inside a module.
Here is the _isTemplateOverloadedStatic() method from Module class called everytime we need a module template:
/*
** Template management (display, overload, cache)
*/
protected static function _isTemplateOverloadedStatic($module_name, $template)
{
if (Tools::file_exists_cache(_PS_THEME_DIR_.'modules/'.$module_name.'/'.$template)) {
return _PS_THEME_DIR_.'modules/'.$module_name.'/'.$template;
} elseif (Tools::file_exists_cache(_PS_THEME_DIR_.'modules/'.$module_name.'/views/templates/hook/'.$template)) {
return _PS_THEME_DIR_.'modules/'.$module_name.'/views/templates/hook/'.$template;
} elseif (Tools::file_exists_cache(_PS_THEME_DIR_.'modules/'.$module_name.'/views/templates/front/'.$template)) {
return _PS_THEME_DIR_.'modules/'.$module_name.'/views/templates/front/'.$template;
} elseif (Tools::file_exists_cache(_PS_MODULE_DIR_.$module_name.'/views/templates/hook/'.$template)) {
return false;
} elseif (Tools::file_exists_cache(_PS_MODULE_DIR_.$module_name.'/views/templates/front/'.$template)) {
return false;
} elseif (Tools::file_exists_cache(_PS_MODULE_DIR_.$module_name.'/'.$template)) {
return false;
}
return null;
}
As you can see in this code, Prestashop will never look into a themes folder inside your module when loading a template.

Prestashop: duplicate Invoice PDF with new tpl

How can I duplicate the Generate Invoice PDF Process in Prestashop? I want to use a different tpl file, but the rest should stay the same.
Let me explain, what I already did:
HTMLTemplateInvoice as HTMLTemplateMahnung and changed Class Name.
Added: const TEMPLATE_MAHNUNG = 'Mahnung'; to the file classes/pdf/PDF.php
Created file mahnung.tpl in root/pdf folder
Added to AdminPdfController.php:
public function processGenerateMahnungPdf() {
if (Tools::isSubmit('id_order')) {
$this->generateMahnungPDFByIdOrder(Tools::getValue('id_order'));
} elseif (Tools::isSubmit('id_order_invoice')) {
$this->generateInvoicePDFByIdOrderInvoice(Tools::getValue('id_order_invoice'));
} else {
die(Tools::displayError('The order ID -- or the invoice order ID -- is missing.'));
}}
AND
public function generateMahnungPDFByIdOrder($id_order)
{
$order = new Order((int)$id_order);
if (!Validate::isLoadedObject($order)) {
die(Tools::displayError('The order cannot be found within your database.'));
}
$order_invoice_list = $order->getInvoicesCollection();
Hook::exec('actionPDFInvoiceRender', array('order_invoice_list' => $order_invoice_list));
$this->generatePDF($order_invoice_list, PDF::TEMPLATE_MAHNUNG);
}
But it's not working. It just doesn't generate the PDF.
Any help?
UPDATE
I had to include the class: require_once _PS_ROOT_DIR_ . '/classes/pdf/HTMLTemplateMahnung.php';
Now its working. Anybody knows why I had to this? I don't see any includes of Core Files :S
Pretashop uses the file cache/class_index.php to keep track of the classes it needs.
Everytime you add a new override, or even a class or controller, you need to delete (or rename) this file. If it doesn't find it, Prestashop will recreate indexing all files in set folders (classes, controllers, overrides, and others).

module creation in suiteCRM

I am using SuiteCRM ( Sugar CRM 6.x community edition ) & want to create a custom login page and after successful login I want to redirect based on user type
tried to create some modules but there is no clear documentation except few of useful links, below are my queries :
Can we create custom modules without using module builder, if yes then what would be steps?
Do we need to write module in /module folder or /custom/module folder or on both place?
any link is also appreciated.
You can create a custom Login Page by modfying "modules/Users/login.tpl"
Custom Modules can be created through Modulebuilder or manually.
When creating modules manually it's important to use the right names.
The easiest way is a Plural name for the folder, table and Module and a singular name for the class.
Manual steps:
You need a Folder in modules/ named like you module (i.e. CAccounts)
In this folder you need a file named like the class (i.e CAccount.php) with something like that as content:
require_once('data/SugarBean.php');
require_once('include/utils.php');
class CAccount extends SugarBean{
var $table_name = 'caccounts';
var $object_name = 'CAccount';
var $module_dir = 'CAccounts';
var $new_schema = true;
var $name;
var $created_by;
var $id;
var $deleted;
var $date_entered;
var $date_modified;
var $modified_user_id;
var $modified_by_name;
function CAccount (){
parent::SugarBean();
}
function get_summary_text(){
return $this->name;
}
function bean_implements($interface)
{
switch($interface)
{
case 'ACL':return true;
}
return false;
}
}
In this folder you need a vardefs.php file:
$dictionary['CAccount'] = array(
'table'=>'caccounts',
'audited'=>false,
'fields'=>array (
//Your fielddefs here
)
);
require_once('include/SugarObjects/VardefManager.php');
VardefManager::createVardef('CAccounts','CAccount', array('basic'));
For the language and metadata folders look at any other module.
Next is a file at "custom/Extension/application/Ext/Include/CAccounts.include.php"
$moduleList[] = 'CAccounts';
$beanList['CAccounts'] = 'CAccount';
$beanFiles['CAccount'] = 'modules/CAccounts/CAccount.php';
A language file for the module name must be in "custom/Extension/application/Ext/Language/"
$app_list_strings['moduleList']['CAccounts'] = 'Custom Accounts';
To display the Module in your tabs you need to use "rebuild and repair" and then the "Display Modules and Subpanels" option in the admin menu.
For a custom module you don't need the "custom/" folder structure. Files there will be used by sugar if provided, but often there's no need for that in a custom module.
Guides about the Module Framework can be found on the sugarcrm support site:
http://support.sugarcrm.com/02_Documentation/04_Sugar_Developer/Sugar_Developer_Guide_6.5/03_Module_Framework

yii create a clean app without assets

I use ./yiic webapp /path/to/name create a project, but I don't need some file that created.
Actual:
assets css images index.php index-test.php protected themes
Expected:
index.php protected
Where is template that I should to change.
If you wish to really change this you should extend ( or modify) the class WebAppCommand that is part of the framework. It can be found in
Yii
-> Framework
->cli
-> commands
->WebAppCommand.php
Instead of modifying the exisiting code i suggest you write a custom class that extends WebAppCommand class and just remove the directories in separate method that calls the run method of WebAppCommand and adds additional lines to delete the unnecessary directories.
Perhaps something like this...
<?php
class MyCustomWebAppCommand extends WebAppCommand {
private $_rootPath; // Need to redefine and compute this as thevariable is defined as private in the parent class and better not touch core classes;
public function run($args){
parent::run($args);
$path=strtr($args[0],'/\\',DIRECTORY_SEPARATOR);
if(strpos($path,DIRECTORY_SEPARATOR)===false)
$path='.'.DIRECTORY_SEPARATOR.$path;
if(basename($path)=='..')
$path.=DIRECTORY_SEPARATOR.'.';
$dir=rtrim(realpath(dirname($path)),'\\/');
if($dir===false || !is_dir($dir))
$this->usageError("The directory '$path' is not valid. Please make sure the parent directory exists.");
if(basename($path)==='.')
$this->_rootPath=$path=$dir;
else
$this->_rootPath=$path=$dir.DIRECTORY_SEPARATOR.basename($path);
$this->deleteDir($this->_rootPath.DIRECTORY_SEPARATOR."assets");
$this->deleteDir($this->_rootPath.DIRECTORY_SEPARATOR."themes");
$this->deleteDir($this->_rootPath.DIRECTORY_SEPARATOR."images");
$this->deleteDir($this->_rootPath.DIRECTORY_SEPARATOR."css");
unset($this->_rootPath.DIRECTORY_SEPARATOR."index-test.php");
}
public static function deleteDir($dirPath) {
if (! is_dir($dirPath)) {
throw new InvalidArgumentException("$dirPath must be a directory");
}
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
$dirPath .= '/';
}
$files = glob($dirPath . '*', GLOB_MARK);
foreach ($files as $file) {
if (is_dir($file)) {
self::deleteDir($file);
} else {
unlink($file);
}
}
rmdir($dirPath);
}
}
Finally call MyCustomWebApp instead of calling WebApp.
P.S. I would generally suggest not to extend/modify core classes without knowing what you are doing, it will break lot of things in places you won't anticipate, and upgrades become extremely difficult. Simpler in your case is to delete the files manually.