Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
en:extensions:workflowdesigner:developers [2014/12/09 12:45] swarnat |
en:extensions:workflowdesigner:developers [2016/07/22 12:38] (current) swarnat |
||
---|---|---|---|
Line 8: | Line 8: | ||
This files will be overwritten with every update and your modifications are lost. | This files will be overwritten with every update and your modifications are lost. | ||
</WRAP> | </WRAP> | ||
+ | |||
+ | All already existing core extension files, are installed in plain PHP code and not be encrypted! | ||
==== Add functions you could use in custom expressions ==== | ==== Add functions you could use in custom expressions ==== | ||
Line 41: | Line 43: | ||
</code> | </code> | ||
- | ==== You build a module, which create files you want to integrate into Workflows? ==== | + | ==== You have a module, which create files you want to integrate into Workflows? ==== |
<WRAP right round info 40%> | <WRAP right round info 40%> | ||
Line 47: | Line 49: | ||
</WRAP> | </WRAP> | ||
- | **PDFMaker and SQLReports is implemented in this way!** | + | **PDFMaker and SQLReports are implemented in this way!** |
If you create a similar module you could create a interfacefile to attach this files to Mails, Store as Documents or simple use the file in every task, which could handle files in any way. | If you create a similar module you could create a interfacefile to attach this files to Mails, Store as Documents or simple use the file in every task, which could handle files in any way. | ||
Line 57: | Line 59: | ||
<code php> | <code php> | ||
<?php | <?php | ||
- | /** | ||
- | * Created by JetBrains PhpStorm. | ||
- | * User: Stefan Warnat <support@stefanwarnat.de> | ||
- | * Date: 01.06.14 12:04 | ||
- | * You must not use this file without permission. | ||
- | */ | ||
namespace Workflow\Plugins\InterfaceFiles; | namespace Workflow\Plugins\InterfaceFiles; | ||
- | class SQLReports extends \Workflow\InterfaceFiles { | + | class [ModuleName] extends \Workflow\InterfaceFiles { |
- | protected $title = 'SQL Reports'; | + | protected $title = '[ModuleName]'; |
- | protected $key = 'sqlreport'; | + | protected $key = '[SanitizedModuleName]'; |
public function __construct() { | public function __construct() { | ||
Line 75: | Line 71: | ||
} | } | ||
- | protected function _getFile($id, $moduleName, $crmid) { | + | /** |
+ | * @var String $moduleName The module of the current Workflow | ||
+ | * @return array - array( | ||
+ | * 'filekeyA' => 'File title of the first file from this module', | ||
+ | * ... | ||
+ | * ) | ||
+ | * | ||
+ | * The file title will be shown in the task configurations. | ||
+ | * The filekey will be given to your _getFile and should uniquely identify the file you should generate | ||
+ | */ | ||
+ | protected function _getAvailableFiles($moduleName) { | ||
+ | $return = array(); | ||
if(!$this->isModuleActive()) { | if(!$this->isModuleActive()) { | ||
- | return false; | + | return $return; |
} | } | ||
- | $adb = \PearDatabase::getInstance(); | ||
- | $parts = explode('#', $id); | ||
- | $tmpFilename = $this->_getTmpFilename(); | + | /* |
+ | This function must simple return an array, like this: | ||
+ | array( | ||
+ | 'filekeyA' => 'File title of this file' | ||
+ | ) | ||
- | if($parts[0] == 'pdf') { | + | */ |
+ | return $return; | ||
+ | } | ||
+ | | ||
+ | /** | ||
+ | * @var String $key - The fileKey you set in the _getAvailableFiles function | ||
+ | * @var String $moduleName - The module from the given RecordID, which should be used to generate the file | ||
+ | * @var Int $crmid - The ID of the Record, which should be used to generate the file | ||
+ | * @return array - An Array with the following Structure | ||
+ | * array( | ||
+ | * 'path' => "<temporarily path to the generated file>", | ||
+ | * 'type' => "<mime type of the generated file>", | ||
+ | * 'name' => "<filename of the generated file>" | ||
+ | * ); | ||
+ | * The filename will probably overwritten by some tasks, | ||
+ | * but if not, it will be used to give this file to the user. | ||
+ | */ | ||
+ | protected function _getFile($key, $moduleName, $crmid) { | ||
+ | if(!$this->isModuleActive()) { | ||
+ | return false; | ||
} | } | ||
+ | | ||
+ | return array( | ||
+ | 'path' => "<temporarily path to the generated file>", | ||
+ | 'type' => "<mime type of the generated file>", | ||
+ | 'name' => "<filename of the generated file>" | ||
+ | ); | ||
+ | } | ||
+ | public function isModuleActive() { | ||
+ | return getTabid('[moduleName]') && vtlib_isModuleActive('[moduleName]'); | ||
+ | } | ||
+ | } | ||
- | $sql = 'SELECT * FROM vtiger_sqlreports WHERE sqlreportsid = '.$parts[1]; | + | // This will register this class in the Interface Registry |
- | $result = $adb->query($sql); | + | \Workflow\InterfaceFiles::register('[SanitizedModuleName]', '\Workflow\Plugins\InterfaceFiles\[ModuleName]'); |
- | $row = $adb->fetchByAssoc($result); | + | </code> |
+ | ==== Add new Options what to do with Files generated by Workflows ==== | ||
+ | With 600.0801 in added this interface. It will be integrated in every tasks in the next versions. | ||
+ | At this moment it is only integrated into the new PDFMaker Integration block. | ||
- | switch($parts[0]) { | + | Add a file in **/modules/Workflow2/extends/fileactions/** with the filename "<individual>.inc.php" |
- | case 'pdf': | + | |
- | $file_name = "Report_".preg_replace('/[^A-Za-z0-9-_]/', '_', $row['reportname']).".pdf"; | + | |
- | $this->_createPDF($tmpFilename, $parts[1]); | + | |
- | $type = 'application/pdf'; | + | |
- | break; | + | |
- | case 'xls': | + | |
- | $file_name = "Report_".preg_replace('/[^A-Za-z0-9-_]/', '_', $row['reportname']).".xls"; | + | |
- | $this->_createXLS($tmpFilename, $parts[1]); | + | |
- | $type = 'application/x-msexcel'; | + | |
- | break; | + | |
- | case 'csv': | + | |
- | $file_name = "Report_".preg_replace('/[^A-Za-z0-9-_]/', '_', $row['reportname']).".csv"; | + | |
- | $this->_createCSV($tmpFilename, $parts[1]); | + | |
- | $type = 'application/csv'; | + | |
- | break; | + | |
- | } | + | |
- | return array( | + | This file must contain a class which extends from **\Workflow\FileAction**. |
- | 'path' => $tmpFilename, | + | This class must have the following structure: |
- | 'type' => $type, | + | |
- | 'name' => $file_name | + | <code php> |
- | ); | + | <?php |
+ | namespace Workflow\Plugins\FileActions; | ||
+ | |||
+ | class [IndividualNameA] extends \Workflow\FileAction { | ||
+ | |||
+ | /** | ||
+ | * @param String $moduleName - The module from the workflow, this action will be used | ||
+ | * @return array - Returns an array with the Option, this file could provide: | ||
+ | * array( | ||
+ | 'title' => '<title of this FileAction (could be translated in lang Files)>', | ||
+ | 'options' => $options | ||
+ | ) | ||
+ | |||
+ | $options is also an array with configuration options, | ||
+ | the User should input, if he choose this action | ||
+ | $options = array( | ||
+ | '<configKeyA>' => array( | ||
+ | 'type' => '<templatefield|templatearea|picklist|checkbox>', | ||
+ | 'label' => '<label show before this configuration option (could be translated)', | ||
+ | 'placeholder' => '<placeholder of input field>, | ||
+ | // if type = checkbox | ||
+ | // 'value' => 1 | ||
+ | // if type = picklist | ||
+ | // 'options' => array('ID1' => 'value1', 'ID2' => 'value2', ...) | ||
+ | ), | ||
+ | ... | ||
+ | ) | ||
+ | */ | ||
+ | public function getActions($moduleName) { | ||
+ | $return = array(); | ||
+ | |||
+ | return $return; | ||
} | } | ||
- | private function _createPDF($tmpFile, $reportId) { | ||
- | $reportModel = \SQLReports_Record_Model::getInstanceById($reportId); | ||
- | $pdf = $reportModel->getReportPDF(); | ||
- | $pdf->Output($tmpFile, 'F'); | + | /** |
+ | * @param array $configuration - Array with all configuration options, the user configure | ||
+ | * @param string $filepath - The temporarily filepath of the file, which should be transformed | ||
+ | * @param string $filename - The filename of this file | ||
+ | * @param \Workflow\VTEntity $context - The Context of the Workflow | ||
+ | * @param array $targetRecordIds | ||
+ | * @return void | ||
+ | */ | ||
+ | public function doAction($configuration, $filepath, $filename, $context, $targetRecordIds = array()) { | ||
} | } | ||
- | private function _createCSV($tmpFile, $reportId) { | ||
- | vimport('~~/modules/SQLReports/ReportRunSQL.php'); | ||
- | $reportRun = \ReportRunSQL::getInstance($reportId); | ||
- | $reportRun->writeReportToCSVFile($tmpFile, false); | ||
- | } | ||
- | private function _createXLS($tmpFile, $reportId) { | ||
- | vimport('~~/modules/SQLReports/ReportRunSQL.php'); | ||
- | /** | ||
- | * @var $reportRun \ReportRunSQL | ||
- | */ | ||
- | $reportRun = \ReportRunSQL::getInstance($reportId); | ||
- | $reportRun->writeReportToExcelFile($tmpFile, false); | ||
- | } | ||
- | protected function _getAvailableFiles($moduleName) { | ||
- | $return = array(); | ||
- | if(!$this->isModuleActive()) { | ||
- | return $return; | ||
- | } | ||
- | $adb = \PearDatabase::getInstance(); | + | } |
- | $sql = 'SELECT * FROM vtiger_sqlreports ORDER BY reportname'; | + | |
- | $result = $adb->query($sql); | + | |
- | $reports = array(); | + | |
- | while($row = $adb->fetchByAssoc($result)) { | + | |
- | $return['pdf#'.$row['sqlreportsid']] = 'SQLReport - '.$row["reportname"]. ' PDF'; | + | |
- | $return['xls#'.$row['sqlreportsid']] = 'SQLReport - '.$row["reportname"]. ' XLS'; | + | |
- | $return['csv#'.$row['sqlreportsid']] = 'SQLReport - '.$row["reportname"]. ' CSV'; | + | |
- | } | + | |
- | return $return; | + | \Workflow\FileAction::register('[SanitizedIndividualNameA]', '\Workflow\Plugins\FileActions\[IndividualNameA]'); |
+ | </code> | ||
+ | |||
+ | |||
+ | ==== Add a FieldType for Request Values from User ==== | ||
+ | |||
+ | You would like to request a very special value from your users and you couldn't do this with the integrated field types? | ||
+ | **You could integrate you own fieldtypes!** | ||
+ | |||
+ | Add a file in **/modules/Workflow2/extends/fieldtypes/** with the filename "<individual>.inc.php" | ||
+ | |||
+ | This file must contain a class which extends from **\Workflow\Fieldtype**. | ||
+ | This class must have the following structure: | ||
+ | |||
+ | <code php> | ||
+ | <?php | ||
+ | namespace Workflow\Plugins\Fieldtypes; | ||
+ | |||
+ | class [IndividualNameA] extends \Workflow\Fieldtype | ||
+ | { | ||
+ | /** | ||
+ | * Should return every fieldtype this class will provide | ||
+ | * | ||
+ | * @param $moduleName - The moduleName of the Workflow, which include this field | ||
+ | * @return array - An Array with the following Structure | ||
+ | * array( | ||
+ | * array( | ||
+ | 'id' => '<uniqueFieldTypeID>', | ||
+ | 'title' => '<NameOfFieldType>', | ||
+ | 'config' => $config | ||
+ | * ), ... | ||
+ | * ) | ||
+ | $config is an array of configuration fields, the admin needs to configure in backend | ||
+ | * it must have the following structure | ||
+ | * array( | ||
+ | * '<configKey>' => array( | ||
+ | 'type' => '[templatefield,templatearea,picklist,checkbox]', | ||
+ | * 'label' => '<label Of Configuration Input>', | ||
+ | // if type = checkbox | ||
+ | // 'value' => 1 | ||
+ | // if type = picklist | ||
+ | // 'options' => array('ID1' => 'value1', 'ID2' => 'value2', ...) | ||
+ | * ), ... | ||
+ | * ) | ||
+ | * | ||
+ | */ | ||
+ | public function getFieldTypes($moduleName) { | ||
+ | $fields = array(); | ||
+ | |||
+ | /* | ||
+ | Example: | ||
+ | $fields[] = array( | ||
+ | 'id' => 'reference', | ||
+ | 'title' => 'Referenz', | ||
+ | 'config' => array( | ||
+ | 'reference' => array( | ||
+ | 'type' => 'picklist', | ||
+ | 'label' => 'Referenz', | ||
+ | 'options' => $relmodules, | ||
+ | ) | ||
+ | ) | ||
+ | ); | ||
+ | */ | ||
+ | |||
+ | return $fields; | ||
} | } | ||
- | public function isModuleActive() { | + | |
- | return getTabid('SQLReports') && vtlib_isModuleActive('SQLReports'); | + | /** |
+ | * @param $data - Config Array of this Input with the following Structure | ||
+ | * array( | ||
+ | * 'label' => 'Label the Function should use', | ||
+ | * 'name' => 'The Fieldname, which should used as name attribute', | ||
+ | * 'config' => Key-Value Array with all configurations, done by admin | ||
+ | * ) | ||
+ | * @param \Workflow\VTEntity $context - Current Record, which is assigned to the Workflow | ||
+ | * @return array - The rendered content, shown to the user with the following structure | ||
+ | * array( | ||
+ | * 'html' => '<htmlContentOfThisInputField>', | ||
+ | * 'javascript' => 'A Javascript executed after html is shown' | ||
+ | * ) | ||
+ | * | ||
+ | */ | ||
+ | public function renderFrontend($data, $context) { | ||
+ | $html = ''; | ||
+ | $script = ''; | ||
+ | | ||
+ | return array('html' => $html, 'javascript' => $script); | ||
} | } | ||
} | } | ||
- | \Workflow\InterfaceFiles::register('sqlreport', '\Workflow\Plugins\InterfaceFiles\SQLReports'); | + | // The class neeeds to be registered |
+ | \Workflow\Fieldtype::register('[IndividualNameA]', '\Workflow\Plugins\Fieldtypes\[IndividualNameA]'); | ||
</code> | </code> | ||
+ | |||
+ | ==== add own shortfunctions ==== | ||
+ | |||
+ | If you want to add a custom "shortfunction" you could use with the syntax $[...], then you must do the following. | ||
+ | Create one file, with filename **<custom>.inc.php** in folder modules/Workflow2/extends/shortfunctions/ | ||
+ | |||
+ | Only required code is: | ||
+ | |||
+ | <code> | ||
+ | \Workflow\Shortfunctions::register('shortfunctionname', <CallAble Object>, $parametersShouldBeParsed); | ||
+ | </code> | ||
+ | |||
+ | The callable object could be any callable element, php could execute. For example an closure, or string with function name. Any possible option you see here: [[http://php.net/manual/de/language.types.callable.php]] | ||
+ | |||
+ | And you must implement this callable object with your PHP code. **That's all!** | ||
+ | |||
+ | ==== use custom Inventory Fields ==== | ||
+ | |||
+ | If you implement custom fields in your Inventory Records, like Invoice, Quotes, the values will be deleted during any workflows and you couldn't interact with this values from Workflow Designer before version 600.0825. | ||
+ | With this version, you could create a file named "InventoryFields.inc.php" directly into the "extends" directory. | ||
+ | This file will not be overwritten during updates of the module. | ||
+ | |||
+ | In this file you could configure the fields you create and want to keep during Workflows. | ||
+ | This file **MUST** have the following structure. | ||
+ | Because this file will be included during every Workflow execution in the Inventory Modules, you should proceed with caution. | ||
+ | Every Error in this file could make it impossible to execute any workflows. | ||
+ | |||
+ | <code php> | ||
+ | <?php | ||
+ | /** | ||
+ | * You need to enter the following php structure | ||
+ | * | ||
+ | * return array( | ||
+ | * 'tableCol' => array('inventoryField' => 'FieldNameWithoutProductIndex', 'label' => 'Label of this field'), | ||
+ | * ); | ||
+ | */ | ||
+ | // Example: | ||
+ | |||
+ | return array( | ||
+ | 'test' => array('inventoryField' => 'testCol', 'label' => 'Testvalue'), | ||
+ | ); | ||
+ | </code> | ||
+ | | tableCol | This is the name of the column in the vtiger_inventoryproductrel table. Won't be used to read from database , but will be a good and unique name | | ||
+ | | FieldNameWithoutProductIndex | This is the Key of the value in the ProductsArray. You use this value in the "getAssociatedProducts" function | | ||
+ | | Testvalue | The label of this field, which will be shown on task configurations | | ||
+ | |||
+ | This structure will make it possible to also set this fields if you create an Invoice in an Workflow. |