2014-06-10 15:18:49 +02:00
< ? php
App :: uses ( 'AppController' , 'Controller' );
2014-07-02 16:20:19 +02:00
App :: uses ( 'Folder' , 'Utility' );
App :: uses ( 'File' , 'Utility' );
2014-06-10 15:18:49 +02:00
2018-07-19 11:48:22 +02:00
class TemplatesController extends AppController
{
public $components = array ( 'Security' , 'RequestHandler' );
2014-06-10 15:18:49 +02:00
2018-07-19 11:48:22 +02:00
public $paginate = array (
'limit' => 50 ,
'order' => array (
'Template.id' => 'desc'
)
);
2014-06-10 15:18:49 +02:00
2018-07-19 11:48:22 +02:00
public function beforeFilter ()
{ // TODO REMOVE
parent :: beforeFilter ();
$this -> Security -> unlockedActions = array ( 'uploadFile' , 'deleteTemporaryFile' );
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
public function index ()
{
$conditions = array ();
if ( ! $this -> _isSiteAdmin ()) {
$conditions [ 'OR' ] = array ( 'org' => $this -> Auth -> user ( 'Organisation' )[ 'name' ], 'share' => 1 );
}
if ( ! $this -> _isSiteAdmin ()) {
$this -> paginate = Set :: merge ( $this -> paginate , array (
'conditions' =>
array ( " OR " => array (
array ( 'org' => $this -> Auth -> user ( 'Organisation' )[ 'name' ]),
array ( 'share' => 1 ),
))));
}
$this -> set ( 'list' , $this -> paginate ());
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
public function edit ( $id )
{
$template = $this -> Template -> checkAuthorisation ( $id , $this -> Auth -> user (), true );
if ( ! $this -> _isSiteAdmin () && ! $template ) {
throw new MethodNotAllowedException ( 'No template with the provided ID exists, or you are not authorised to edit it.' );
}
$this -> set ( 'mayModify' , true );
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
if ( $this -> request -> is ( 'post' ) || $this -> request -> is ( 'put' )) {
$this -> request -> data [ 'Template' ][ 'id' ] = $id ;
unset ( $this -> request -> data [ 'Template' ][ 'tagsPusher' ]);
$tags = $this -> request -> data [ 'Template' ][ 'tags' ];
unset ( $this -> request -> data [ 'Template' ][ 'tags' ]);
$this -> request -> data [ 'Template' ][ 'org' ] = $this -> Auth -> user ( 'Organisation' )[ 'name' ];
$this -> Template -> create ();
if ( $this -> Template -> save ( $this -> request -> data )) {
$id = $this -> Template -> id ;
$tagArray = json_decode ( $tags );
$this -> loadModel ( 'TemplateTag' );
$oldTags = $this -> TemplateTag -> find ( 'all' , array (
'conditions' => array ( 'template_id' => $id ),
'recursive' => - 1 ,
'contain' => 'Tag'
));
2014-06-19 08:44:35 +02:00
2018-07-19 11:48:22 +02:00
$newTags = $this -> TemplateTag -> Tag -> find ( 'all' , array (
'recursive' => - 1 ,
'conditions' => array ( 'id' => $tagArray )
));
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
foreach ( $oldTags as $k => $oT ) {
if ( ! in_array ( $oT [ 'Tag' ], $newTags )) {
$this -> TemplateTag -> delete ( $oT [ 'TemplateTag' ][ 'id' ]);
}
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
foreach ( $newTags as $k => $nT ) {
if ( ! in_array ( $nT [ 'Tag' ], $oldTags )) {
$this -> TemplateTag -> create ();
$this -> TemplateTag -> save ( array ( 'TemplateTag' => array ( 'template_id' => $id , 'tag_id' => $nT [ 'Tag' ][ 'id' ])));
}
}
$this -> redirect ( array ( 'action' => 'view' , $this -> Template -> id ));
} else {
throw new Exception ( 'The template could not be edited.' );
}
}
$this -> request -> data = $template ;
2014-06-19 08:44:35 +02:00
2018-07-19 11:48:22 +02:00
// get all existing tags for the tag add dropdown menu
$this -> loadModel ( 'Tags' );
$tags = $this -> Tags -> find ( 'all' );
$tagArray = array ();
foreach ( $tags as $tag ) {
$tagArray [ $tag [ 'Tags' ][ 'id' ]] = $tag [ 'Tags' ][ 'name' ];
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
//get all tags currently assigned to the event
$currentTags = $this -> Template -> TemplateTag -> find ( 'all' , array (
'recursive' => - 1 ,
'contain' => 'Tag' ,
'conditions' => array ( 'template_id' => $id ),
));
$this -> set ( 'currentTags' , $currentTags );
$this -> set ( 'id' , $id );
$this -> set ( 'template' , $template );
$this -> set ( 'tags' , $tagArray );
$this -> set ( 'tagInfo' , $tags );
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
public function view ( $id )
{
if ( ! $this -> _isSiteAdmin () && ! $this -> Template -> checkAuthorisation ( $id , $this -> Auth -> user (), false )) {
throw new MethodNotAllowedException ( 'No template with the provided ID exists, or you are not authorised to see it.' );
}
if ( $this -> Template -> checkAuthorisation ( $id , $this -> Auth -> user (), true )) {
$this -> set ( 'mayModify' , true );
} else {
$this -> set ( 'mayModify' , false );
}
$template = $this -> Template -> find ( 'first' , array (
'conditions' => array (
'id' => $id ,
),
'contain' => array (
'TemplateElement' ,
'TemplateTag' => array (
'Tag' ,
),
),
));
if ( empty ( $template )) {
throw new NotFoundException ( 'No template with the provided ID exists, or you are not authorised to see it.' );
}
$tagArray = array ();
foreach ( $template [ 'TemplateTag' ] as $tt ) {
$tagArray [] = $tt ;
}
$this -> set ( 'id' , $id );
$this -> set ( 'template' , $template );
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
public function add ()
{
if ( ! $this -> userRole [ 'perm_template' ]) {
throw new MethodNotAllowedException ( 'You are not authorised to do that.' );
}
if ( $this -> request -> is ( 'post' )) {
unset ( $this -> request -> data [ 'Template' ][ 'tagsPusher' ]);
$tags = $this -> request -> data [ 'Template' ][ 'tags' ];
unset ( $this -> request -> data [ 'Template' ][ 'tags' ]);
$this -> request -> data [ 'Template' ][ 'org' ] = $this -> Auth -> user ( 'Organisation' )[ 'name' ];
$this -> Template -> create ();
if ( $this -> Template -> save ( $this -> request -> data )) {
$id = $this -> Template -> id ;
$tagArray = json_decode ( $tags );
$this -> loadModel ( 'TemplateTag' );
$this -> loadModel ( 'Tag' );
foreach ( $tagArray as $t ) {
$tag = $this -> Tag -> find ( 'first' , array (
'conditions' => array ( 'id' => $t ),
'fields' => array ( 'id' , 'name' ),
'recursive' => - 1 ,
));
$this -> TemplateTag -> create ();
$this -> TemplateTag -> save ( array ( 'TemplateTag' => array ( 'template_id' => $id , 'tag_id' => $tag [ 'Tag' ][ 'id' ])));
}
$this -> redirect ( array ( 'action' => 'view' , $this -> Template -> id ));
} else {
throw new Exception ( 'The template could not be created.' );
}
}
$this -> loadModel ( 'Tags' );
$tags = $this -> Tags -> find ( 'all' );
$tagArray = array ();
foreach ( $tags as $tag ) {
$tagArray [ $tag [ 'Tags' ][ 'id' ]] = $tag [ 'Tags' ][ 'name' ];
}
$this -> set ( 'tags' , $tagArray );
$this -> set ( 'tagInfo' , $tags );
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
public function saveElementSorting ()
{
// check if user can edit the template
$this -> autoRender = false ;
$this -> request -> onlyAllow ( 'ajax' );
$orderedElements = $this -> request -> data ;
foreach ( $orderedElements as $key => $e ) {
$orderedElements [ $key ] = ltrim ( $e , 'id_' );
}
$extractedIds = array ();
foreach ( $orderedElements as $element ) {
$extractedIds [] = $element ;
}
$template_id = $this -> Template -> TemplateElement -> find ( 'first' , array (
'conditions' => array ( 'id' => $extractedIds ),
'recursive' => - 1 ,
'fields' => array ( 'id' , 'template_id' ),
));
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
if ( ! $this -> _isSiteAdmin () && ! $this -> Template -> checkAuthorisation ( $template_id [ 'TemplateElement' ][ 'template_id' ], $this -> Auth -> user (), true )) {
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => false , 'errors' => 'You are not authorised to do that.' )), 'status' => 200 , 'type' => 'json' ));
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
$elements = $this -> Template -> TemplateElement -> find ( 'all' , array (
'conditions' => array ( 'template_id' => $template_id [ 'TemplateElement' ][ 'template_id' ]),
'recursive' => - 1 ,
));
if ( empty ( $elements )) {
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => false , 'errors' => 'Something went wrong, the supplied template elements don\'t exist, or you are not eligible to edit them.' )), 'status' => 200 ));
}
if ( count ( $elements ) != count ( $orderedElements )) {
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => false , 'errors' => 'Incomplete template element list passed as argument. Expecting ' . count ( $elements ) . ' elements, only received positions for ' . count ( $orderedElements ) . '.' )), 'status' => 200 , 'type' => 'json' ));
}
$template_id = $elements [ 0 ][ 'TemplateElement' ][ 'template_id' ];
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
foreach ( $elements as $key => $e ) {
if ( $template_id !== $e [ 'TemplateElement' ][ 'template_id' ]) {
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => false , 'errors' => 'Cannot sort template elements belonging to separate templates. You should never see this message during legitimate use.' )), 'status' => 200 , 'type' => 'json' ));
}
foreach ( $orderedElements as $k => $orderedElement ) {
if ( $orderedElement == $e [ 'TemplateElement' ][ 'id' ]) {
$elements [ $key ][ 'TemplateElement' ][ 'position' ] = $k + 1 ;
}
}
}
$this -> Template -> TemplateElement -> saveMany ( $elements );
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => true , 'success' => 'Elements repositioned.' )), 'status' => 200 , 'type' => 'json' ));
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
public function delete ( $id )
{
$template = $this -> Template -> checkAuthorisation ( $id , $this -> Auth -> user (), true );
if ( ! $this -> request -> is ( 'post' )) {
throw new MethodNotAllowedException ( 'This action can only be invoked via a post request.' );
}
if ( ! $this -> _isSiteAdmin () && ! $template ) {
throw new MethodNotAllowedException ( 'No template with the provided ID exists, or you are not authorised to edit it.' );
}
if ( $this -> Template -> delete ( $id , true )) {
$this -> Flash -> success ( 'Template deleted.' );
$this -> redirect ( array ( 'action' => 'index' ));
} else {
$this -> Flash -> error ( 'The template could not be deleted.' );
$this -> redirect ( array ( 'action' => 'index' ));
}
}
2016-06-04 01:08:16 +02:00
2014-06-19 08:44:35 +02:00
2018-07-19 11:48:22 +02:00
public function templateChoices ( $id )
{
$this -> loadModel ( 'Event' );
$event = $this -> Event -> find ( 'first' , array (
'conditions' => array ( 'id' => $id ),
'recursive' => - 1 ,
'fields' => array ( 'orgc_id' , 'id' ),
));
if ( empty ( $event ) || ( ! $this -> _isSiteAdmin () && $event [ 'Event' ][ 'orgc_id' ] != $this -> Auth -> user ( 'org_id' ))) {
throw new NotFoundException ( 'Event not found or you are not authorised to edit it.' );
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
$conditions = array ();
if ( ! $this -> _isSiteAdmin ) {
$conditions [ 'OR' ] = array ( 'Template.org' => $this -> Auth -> user ( 'Organisation' )[ 'name' ], 'Template.share' => 1 );
}
$templates = $this -> Template -> find ( 'all' , array (
'recursive' => - 1 ,
'conditions' => $conditions
));
$this -> set ( 'templates' , $templates );
$this -> set ( 'id' , $id );
$this -> render ( 'ajax/template_choices' );
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
public function populateEventFromTemplate ( $template_id , $event_id )
{
$template = $this -> Template -> find ( 'first' , array (
'conditions' => array ( 'Template.id' => $template_id ),
'contain' => array (
'TemplateElement' => array (
'TemplateElementAttribute' ,
'TemplateElementText' ,
'TemplateElementFile'
),
'TemplateTag' => array (
'Tag'
)
),
));
$this -> loadModel ( 'Event' );
$event = $this -> Event -> find ( 'first' , array (
'conditions' => array ( 'id' => $event_id ),
'recursive' => - 1 ,
'fields' => array ( 'id' , 'orgc_id' , 'distribution' ),
));
$this -> set ( 'event' , $event );
if ( empty ( $event )) {
throw new MethodNotAllowedException ( 'Event not found or you are not authorised to edit it.' );
}
if ( empty ( $template )) {
throw new MethodNotAllowedException ( 'Template not found or you are not authorised to edit it.' );
}
if ( ! $this -> _isSiteAdmin ()) {
if ( $event [ 'Event' ][ 'orgc_id' ] != $this -> Auth -> user ( 'org_id' )) {
throw new MethodNotAllowedException ( 'Event not found or you are not authorised to edit it.' );
}
if ( $template [ 'Template' ][ 'org' ] != $this -> Auth -> user ( 'Organisation' )[ 'name' ] && ! $template [ 'Template' ][ 'share' ]) {
throw new MethodNotAllowedException ( 'Template not found or you are not authorised to use it.' );
}
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
$this -> set ( 'template_id' , $template_id );
$this -> set ( 'event_id' , $event_id );
if ( $this -> request -> is ( 'post' )) {
$this -> set ( 'template' , $this -> request -> data );
$result = $this -> Event -> Attribute -> checkTemplateAttributes ( $template , $this -> request -> data , $event_id );
if ( isset ( $this -> request -> data [ 'Template' ][ 'modify' ]) || ! empty ( $result [ 'errors' ])) {
$fileArray = $this -> request -> data [ 'Template' ][ 'fileArray' ];
$this -> set ( 'fileArray' , $fileArray );
$this -> set ( 'errors' , $result [ 'errors' ]);
$this -> set ( 'templateData' , $template );
$this -> set ( 'validTypeGroups' , $this -> Event -> Attribute -> validTypeGroups );
} else {
$this -> set ( 'errors' , $result [ 'errors' ]);
$this -> set ( 'attributes' , $result [ 'attributes' ]);
$fileArray = $this -> request -> data [ 'Template' ][ 'fileArray' ];
$this -> set ( 'fileArray' , $fileArray );
$this -> set ( 'distributionLevels' , $this -> Event -> Attribute -> distributionLevels );
$this -> render ( 'populate_event_from_template_attributes' );
}
} else {
$this -> set ( 'templateData' , $template );
$this -> set ( 'validTypeGroups' , $this -> Event -> Attribute -> validTypeGroups );
}
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
// called when the user is finished populating a template and is has finished reviewing the resulting attributes at the last stage of the process
public function submitEventPopulation ( $template_id , $event_id )
{
if ( $this -> request -> is ( 'post' )) {
$this -> loadModel ( 'Event' );
$event = $this -> Event -> find ( 'first' , array (
'conditions' => array ( 'id' => $event_id ),
'recursive' => - 1 ,
'fields' => array ( 'id' , 'orgc_id' , 'distribution' , 'published' ),
'contain' => 'EventTag' ,
));
if ( empty ( $event )) {
throw new MethodNotAllowedException ( 'Event not found or you are not authorised to edit it.' );
}
if ( ! $this -> _isSiteAdmin ()) {
if ( $event [ 'Event' ][ 'orgc_id' ] != $this -> Auth -> user ( 'org_id' )) {
throw new MethodNotAllowedException ( 'Event not found or you are not authorised to edit it.' );
}
}
2014-07-02 16:20:19 +02:00
2018-07-19 11:48:22 +02:00
$template = $this -> Template -> find ( 'first' , array (
'conditions' => array ( 'Template.id' => $template_id ),
'recursive' => - 1 ,
'contain' => 'TemplateTag' ,
'fields' => 'id' ,
));
foreach ( $template [ 'TemplateTag' ] as $tag ) {
$exists = false ;
foreach ( $event [ 'EventTag' ] as $eventTag ) {
if ( $eventTag [ 'tag_id' ] == $tag [ 'tag_id' ]) {
$exists = true ;
}
}
if ( ! $exists ) {
$this -> Event -> EventTag -> create ();
$this -> Event -> EventTag -> save ( array ( 'event_id' => $event_id , 'tag_id' => $tag [ 'tag_id' ]));
}
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
if ( isset ( $this -> request -> data [ 'Template' ][ 'attributes' ])) {
$attributes = json_decode ( $this -> request -> data [ 'Template' ][ 'attributes' ], true );
$this -> loadModel ( 'Attribute' );
$fails = 0 ;
foreach ( $attributes as $k => $attribute ) {
if ( isset ( $attribute [ 'data' ]) && $this -> Template -> checkFilename ( $attribute [ 'data' ])) {
$file = new File ( APP . 'tmp/files/' . $attribute [ 'data' ]);
$content = $file -> read ();
$attributes [ $k ][ 'data' ] = base64_encode ( $content );
if ( $this -> Event -> Attribute -> typeIsMalware ( $attributes [ $k ][ 'type' ])) {
$hashes = $this -> Event -> Attribute -> handleMaliciousBase64 ( $event_id , explode ( '|' , $attributes [ $k ][ 'value' ])[ 0 ], $attributes [ $k ][ 'data' ], array ( 'md5' ));
$attributes [ $k ][ 'data' ] = $hashes [ 'data' ];
}
$file -> delete ();
}
$this -> Attribute -> create ();
if ( ! $this -> Attribute -> save ( array ( 'Attribute' => $attributes [ $k ]))) {
$fails ++ ;
}
}
$count = isset ( $k ) ? $k + 1 : 0 ;
$event = $this -> Event -> find ( 'first' , array (
'conditions' => array ( 'Event.id' => $event_id ),
'recursive' => - 1
));
$event [ 'Event' ][ 'published' ] = 0 ;
$date = new DateTime ();
$event [ 'Event' ][ 'timestamp' ] = $date -> getTimestamp ();
$this -> Event -> save ( $event );
if ( $fails == 0 ) {
$this -> Flash -> success ( __ ( 'Event populated, ' . $count . ' attributes successfully created.' ));
} else {
$this -> Flash -> success ( __ ( 'Event populated, but ' . $fails . ' attributes could not be saved.' ));
}
$this -> redirect ( array ( 'controller' => 'events' , 'action' => 'view' , $event_id ));
} else {
throw new MethodNotAllowedException ( 'No attributes submitted for creation.' );
}
} else {
throw new MethodNotAllowedException ();
}
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
public function uploadFile ( $elementId , $batch )
{
$this -> layout = 'iframe' ;
$this -> set ( 'batch' , $batch );
$this -> set ( 'element_id' , $elementId );
if ( $this -> request -> is ( 'get' )) {
$this -> set ( 'element_id' , $elementId );
} elseif ( $this -> request -> is ( 'post' )) {
$fileArray = array ();
$filenames = array ();
$added = 0 ;
$failed = 0 ;
// filename checks
foreach ( $this -> request -> data [ 'Template' ][ 'file' ] as $k => $file ) {
if ( $file [ 'size' ] > 0 && $file [ 'error' ] == 0 ) {
if ( $this -> Template -> checkFilename ( $file [ 'name' ])) {
$fn = $this -> Template -> generateRandomFileName ();
move_uploaded_file ( $file [ 'tmp_name' ], APP . 'tmp/files/' . $fn );
$filenames [] = $file [ 'name' ];
$fileArray [] = array ( 'filename' => $file [ 'name' ], 'tmp_name' => $fn , 'element_id' => $elementId );
$added ++ ;
} else {
$failed ++ ;
}
} else {
$failed ++ ;
}
}
$result = $added . ' files uploaded.' ;
if ( $failed ) {
$result .= ' ' . $failed . ' files either failed to upload, or were empty.' ;
$this -> set ( 'upload_error' , true );
} else {
$this -> set ( 'upload_error' , false );
}
$this -> set ( 'result' , $result );
$this -> set ( 'filenames' , $filenames );
$this -> set ( 'fileArray' , json_encode ( $fileArray ));
}
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
// deletes a temporary file created by the user while populating a template
// users can add files to attachment fields and when they change their mind about it, they can remove a file (deleting the temporary file)
// before it gets saved as an attribute and moved to the persistent attachment store
public function deleteTemporaryFile ( $filename )
{
if ( ! $this -> request -> is ( 'post' )) {
throw new MethodNotAllowedException ( 'This action is restricted to accepting POST requests only.' );
}
if ( ! $this -> request -> is ( 'ajax' )) {
throw new MethodNotAllowedException ( 'This action is only accessible through AJAX.' );
}
$this -> autoRender = false ;
if ( $this -> Template -> checkFilename ( $filename )) {
$file = new File ( APP . 'tmp/files/' . $filename );
if ( $file -> exists ()) {
$file -> delete ();
}
}
}
2014-06-10 15:18:49 +02:00
}