Changeset 5514
- Timestamp:
- 02/14/12 16:52:04 (11 years ago)
- Location:
- trunk
- Files:
-
- 11 added
- 34 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/expressoCalendar/setup/default_records.inc.php
r5341 r5514 28 28 $oProc->query("ALTER TABLE calendar_signature ADD CONSTRAINT fk_calendar_signature_calendar_espec FOREIGN KEY (calendar_id) REFERENCES calendar (id) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE;"); 29 29 30 30 //calendar_signature_alarm 31 31 $oProc->query("ALTER TABLE calendar_signature_alarm ADD CONSTRAINT fk_calendar_signature_alarm_calendar_signature FOREIGN KEY (calendar_signature_id) REFERENCES calendar_signature (id) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE;"); 32 32 … … 37 37 $oProc->query("INSERT INTO calendar_object_type( \"id\", \"name\") VALUES ('1','VEVENT');"); 38 38 $oProc->query("INSERT INTO calendar_class( \"id\", \"name\") VALUES ('1','Public'),('2','Private'),('3','Confidential');"); 39 $oProc->query("INSERT INTO calendar_participant_status( \"id\", \"name\") VALUES ('1','CONFIRMED'),('2','TENTATIVE'),('3','CANCELLED'),('4','UNANSWERED') ;");39 $oProc->query("INSERT INTO calendar_participant_status( \"id\", \"name\") VALUES ('1','CONFIRMED'),('2','TENTATIVE'),('3','CANCELLED'),('4','UNANSWERED'),('5', 'DELEGATED');"); 40 40 41 41 ?> -
trunk/expressoCalendar/setup/tables_current.inc.php
r5441 r5514 31 31 'type' => array('type' => 'varchar','precision' => '50','nullable' => False), 32 32 'name' => array('type' => 'varchar','precision' => '255','nullable' => False), 33 'size' => array('type' => 'varchar','precision' => '255','nullable' => False) 33 'size' => array('type' => 'varchar','precision' => '255','nullable' => False), 34 'owner' => array('type' => 'int', 'precision' => '8','nullable' => True) 34 35 ), 35 36 'pk' => array('id'), … … 38 39 'uc' => array() 39 40 ), 40 41 42 41 43 42 'calendar' => array( 44 43 'fd' => array( … … 136 135 'user_info_id' => array( 'type' => 'int', 'precision' => '8', 'nullable' => False), 137 136 'object_id' => array( 'type' => 'int', 'precision' => '8', 'nullable' => True), 138 'delegated_ to' => array( 'type' => 'int', 'precision' => '8','default' => 0, 'nullable' => False),137 'delegated_from' => array( 'type' => 'int', 'precision' => '8','default' => 0, 'nullable' => False), 139 138 'is_organizer' => array( 'type' => 'int', 'precision' => '2', 'default' => 0, 'nullable' => False), 140 139 'is_external' => array( 'type' => 'int', 'precision' => '2', 'default' => 0, 'nullable' => False), 141 'participant_status_id' => array( 'type' => 'int', 'precision' => '8', 'nullable' => false , 'default' => 4) 140 'participant_status_id' => array( 'type' => 'int', 'precision' => '8', 'nullable' => false , 'default' => 4), 141 'acl' => array('type' => 'varchar', 'precision' => '10' ,'default' => 'r', 'nullable' => False), 142 'receive_notification' => array( 'type' => 'int', 'precision' => '2', 'default' => 1, 'nullable' => False) 142 143 ), 143 144 'pk' => array('id'), -
trunk/expressoMail1_2/inc/class.db_functions.inc.php
r5509 r5514 410 410 $_REQUEST['params']['calendar'] = $params['selected']; 411 411 $_REQUEST['readable'] = $params['readable'] ? true : false; 412 $_REQUEST['analize'] = isset($params['readable']) ? true : false;412 $_REQUEST['analize'] = isset($params['analize']) ? true : false; 413 413 $_REQUEST['params']['status'] = $params['status']; 414 414 $_REQUEST['params']['owner'] = $_SESSION['phpgw_info']['expressomail']['user']['account_id']; 415 if(isset($params['acceptedSuggestion'])){ 416 $_REQUEST['params']['acceptedSuggestion'] = $params['acceptedSuggestion']; 417 $_REQUEST['params']['from'] = $params['from']; 418 } 419 415 420 ob_start(); 416 421 include_once(PHPGW_INCLUDE_ROOT.'/prototype/converter.php'); -
trunk/expressoMail1_2/js/main.js
r5506 r5514 3633 3633 closeOnEscape: true 3634 3634 }); 3635 $.ajax({ 3636 url: "controller.php?action="+import_url+'&from_ajax=true&id_user='+User.me.id+'&readable=true&cirus_delimiter='+cyrus_delimiter+'&analize=true', 3637 async: false, 3638 success: function(data){ 3639 data = connector.unserialize(data); 3640 3641 3642 var createDialog = function(typeImport, propaget){ 3643 3644 if(typeImport == '1'){ 3645 $("#select-agenda").html(''); 3646 for(var calendario in Calendar.calendarIds){ 3647 var doc = document .createElement("OPTION"); 3648 doc.value = Calendar.signatures[parseInt(calendario)].calendar.id; 3649 doc.innerHTML = Calendar.signatures[parseInt(calendario)].calendar.name; 3650 $("#select-agenda").append(doc); 3651 3652 }; 3653 $("#import-dialog" ).dialog({ 3654 buttons: { 3655 Cancel: function() { 3656 $( this ).dialog( "close" ); 3657 }, 3658 "Importar" : function(){ 3659 3660 $.ajax({ 3661 url: "controller.php?action="+import_url+'&from_ajax=true&selected='+$("#select-agenda option:selected").val()+'&status='+$("#select-status option:selected").val(), 3662 success: function(msg){ 3663 3664 var alt = ( (msg = connector.unserialize(msg)) == "ok") ? "Importado com sucesso para " : "Ocorreu um erro ao importar o evento para a agenda "; 3665 alert( alt + $("#select-agenda option:selected").text() ); 3666 } 3667 }); 3668 3669 $( this ).dialog( "close" ); 3670 } 3671 } 3672 }); 3673 3674 }else if(data == '4'){ 3675 alert('Seu evento já se encontra atualizado'); 3676 return; 3677 }else if(data == '3'){ 3678 $.ajax({ 3679 url: "controller.php?action="+import_url+'&from_ajax=true&selected=true', 3680 success: function(msg){ 3681 alert( ( ( connector.unserialize(msg)) == "ok") ? "Seu evento foi removido " : "Ocorreu um erro ao remover o evento" ); 3682 } 3683 }); 3684 return; 3685 } 3686 else if(data == '5'){ 3687 $.ajax({ 3688 url: "controller.php?action="+import_url+'&from_ajax=true&selected=true', 3689 success: function(msg){ 3690 alert( ( ( connector.unserialize(msg)) == "ok") ? "Atualizado com sucesso " : "Ocorreu um erro ao atualizar o evento" ); 3691 } 3692 }); 3693 return; 3694 }else { 3695 up = true; 3696 $("#select-agenda").css("display", "none"); 3697 $("#import-dialog" ).children("p:first-child").css("display", "none"); 3698 $("#import-dialog" ).dialog({ 3699 height: 160, 3700 title: 'Atualizar Evento', 3701 buttons: { 3702 Cancel: function() { 3703 $( this ).dialog( "close" ); 3704 }, 3705 "Atualizar": function() { 3706 3707 $.ajax({ 3708 url: "controller.php?action="+import_url+'&from_ajax=true&selected='+$("#select-agenda option:selected").val()+'&status='+$("#select-status option:selected").val(), 3709 success: function(msg){ 3710 alert( ( (msg = connector.unserialize(msg)) == "ok") ? "Atualizado com sucesso para " : "Ocorreu um erro ao atualizar o evento" ); 3711 } 3712 }); 3713 3714 $( this ).dialog( "close" ); 3715 } 3716 } 3717 }); 3718 $(".ui-dialog-buttonpane").find(".ui-button:last").children().html("Atualizar"); 3719 }; 3720 $( "#import-dialog" ).dialog( "open" ); 3721 }; 3722 createDialog(data, true); 3635 $.ajax({ 3636 url: "controller.php?action="+import_url+'&from_ajax=true&id_user='+User.me.id+'&readable=true&cirus_delimiter='+cyrus_delimiter+'&analize=true', 3637 async: false, 3638 success: function(data){ 3639 data = connector.unserialize(data); 3640 3641 3642 var createDialog = function(typeImport, propaget){ 3643 3644 switch(parseInt(typeImport)){ 3645 case 1: 3646 $("#select-agenda").html(''); 3647 for(var calendario in Calendar.calendarIds){ 3648 var doc = document .createElement("OPTION"); 3649 doc.value = Calendar.signatures[parseInt(calendario)].calendar.id; 3650 doc.innerHTML = Calendar.signatures[parseInt(calendario)].calendar.name; 3651 $("#select-agenda").append(doc); 3652 3653 }; 3654 $("#import-dialog" ).dialog({ 3655 buttons: { 3656 Cancel: function() { 3657 $( this ).dialog( "close" ); 3658 }, 3659 "Importar" : function(){ 3660 3661 $.ajax({ 3662 url: "controller.php?action="+import_url+'&from_ajax=true&selected='+$("#select-agenda option:selected").val()+'&status='+$("#select-status option:selected").val(), 3663 success: function(msg){ 3664 3665 var alt = ( (msg = connector.unserialize(msg)) == "ok") ? "Importado com sucesso para " : "Ocorreu um erro ao importar o evento para a agenda "; 3666 alert( alt + $("#select-agenda option:selected").text() ); 3667 } 3668 }); 3669 3670 $( this ).dialog( "close" ); 3671 } 3672 } 3673 }); 3674 break; 3675 case 2: 3676 $.ajax({ 3677 url: "controller.php?action="+import_url+'&from_ajax=true&selected=true', 3678 success: function(msg){ 3679 alert( ( ( connector.unserialize(msg)) == "ok") ? "Seu evento foi removido " : "Ocorreu um erro ao remover o evento" ); 3680 } 3681 }); 3682 return; 3683 break; 3684 case 4: 3685 alert('Seu evento já se encontra atualizado'); 3686 return; 3687 break; 3688 case 5: 3689 $.ajax({ 3690 url: "controller.php?action="+import_url+'&from_ajax=true&selected=true', 3691 success: function(msg){ 3692 alert( ( ( connector.unserialize(msg)) == "ok") ? "Atualizado com sucesso " : "Ocorreu um erro ao atualizar o evento" ); 3693 } 3694 }); 3695 return; 3696 break; 3697 case 6: 3698 var acceptedSuggestion = confirm("Deseja atualizar o evento de acordo com a sugestão ?"); 3699 $.ajax({ 3700 url: "controller.php?action="+import_url+'&from_ajax=true&id_user='+User.me.id+'&selected=true&cirus_delimiter='+cyrus_delimiter+'&acceptedSuggestion='+acceptedSuggestion+"&from="+document.getElementById('from_values_'+currentTab).value, 3701 success: function(msg){ 3702 if(acceptedSuggestion) 3703 alert( ( ( connector.unserialize(msg)) == "ok") ? "Evento atualizado com sucesso " : "Ocorreu um erro ao atualizar o evento" ); 3704 } 3705 }); 3706 return; 3707 break; 3708 default: 3709 up = true; 3710 $("#select-agenda").css("display", "none"); 3711 $("#import-dialog" ).children("p:first-child").css("display", "none"); 3712 $("#import-dialog" ).dialog({ 3713 height: 160, 3714 title: 'Atualizar Evento', 3715 buttons: { 3716 Cancel: function() { 3717 $( this ).dialog( "close" ); 3718 }, 3719 "Atualizar": function() { 3720 3721 $.ajax({ 3722 url: "controller.php?action="+import_url+'&from_ajax=true&selected='+$("#select-agenda option:selected").val()+'&status='+$("#select-status option:selected").val(), 3723 success: function(msg){ 3724 alert( ( (msg = connector.unserialize(msg)) == "ok") ? "Atualizado com sucesso para " : "Ocorreu um erro ao atualizar o evento" ); 3725 } 3726 }); 3727 $( this ).dialog( "close" ); 3728 } 3729 } 3730 }); 3731 $(".ui-dialog-buttonpane").find(".ui-button:last").children().html("Atualizar"); 3732 } 3733 $( "#import-dialog" ).dialog( "open" ); 3734 3735 }; 3736 createDialog(data, true); 3723 3737 3724 3738 }}); -
trunk/prototype/Sync.php
r5437 r5514 64 64 if( isset( $dt[$linkName] ) ) 65 65 { 66 if( $notArray = Controller::isConcept( $ linkName ) )66 if( $notArray = Controller::isConcept( $concept, $linkName ) ) 67 67 $dt[$linkName] = array( $dt[$linkName] ); 68 68 -
trunk/prototype/api/controller.php
r5437 r5514 1 1 <?php 2 2 3 3 4 if( !defined( 'ROOTPATH' ) ) … … 25 26 static $includes = array(); 26 27 static $tx = array(); 28 static $isConcept = array(); 27 29 static $txID = 0; 28 30 static $wallet; … … 150 152 151 153 //TODO: Compatibilizar as configs relativas aos modulos, adicionando os mesmo nos parametros passados 152 public static function links( $concept = false ) 153 { 154 public static function links( $concept = false, $linkage = false ) 155 { 156 157 154 158 if( !isset(self::$config[ $concept ]) ) 155 159 self::$config[ $concept ] = self::loadConfig( $concept ); 156 160 157 return( isset(self::$config[ $concept ]['links']) ? 158 self::$config[ $concept ]['links'] : array() ); 159 } 160 161 public static function isConcept( $concept ) 161 $links = array(); 162 self::$isConcept[ $concept ] = array(); 163 164 if( isset(self::$config[ $concept ][ 'model.hasOne' ]) ) 165 foreach( self::$config[ $concept ][ 'model.hasOne' ] as $linkName => $linkTarget ) 166 { 167 list( $target, $link ) = explode( '.', $linkTarget ); 168 169 if( $linkage === $linkName ) 170 $return = $link; 171 172 $links[$linkName] = $target; 173 self::$isConcept[ $concept ][ $linkName ] = true; 174 } 175 if( isset(self::$config[ $concept ][ 'model.depends' ]) ) 176 foreach( self::$config[ $concept ][ 'model.depends' ] as $linkName => $linkTarget ) 177 { 178 list( $target, $link ) = explode( '.', $linkTarget ); 179 180 if( $linkage === $linkName ) 181 $return = $link; 182 183 $links[$linkName] = $target; 184 self::$isConcept[ $concept ][ $linkName ] = true; 185 } 186 if( isset(self::$config[ $concept ][ 'model.hasMany' ]) ) 187 foreach( self::$config[ $concept ][ 'model.hasMany' ] as $linkName => $linkTarget ) 188 { 189 list( $target, $link ) = explode( '.', $linkTarget ); 190 191 if( $linkage === $linkName ) 192 $return = $link; 193 194 $links[$linkName] = $target; 195 } 196 197 return( isset($return) ? $return : $links ); 198 } 199 200 public static function isConcept( $concept, $linkName ) 162 201 { 163 if( isset( self::$config[ $concept ] ) && 164 self::$config[ $concept ] ) 165 return( true ); 166 else 167 return file_exists( ROOTPATH."/config/$concept.ini" ); 202 if( !isset( self::$isConcept[ $concept ] ) ) 203 self::links( $concept ); 204 205 return( isset(self::$isConcept[ $concept ][ $linkName ]) ); 168 206 } 169 207 … … 576 614 577 615 $postpone = array(); 616 $linkNames = array(); 578 617 579 618 if( $data ) … … 585 624 if( isset( $data[$linkName] ) && is_array( $data[$linkName] ) ) 586 625 { 587 if( self::isConcept($linkName ) )626 if( self::isConcept( $URI['concept'], $linkName ) ) 588 627 $data[$linkName] = self::put( array( 'concept' => $linkTarget ), $data[$linkName], &$txIds ); 589 628 else 590 $postpone[$linkTarget] = $data[$linkName]; 629 { 630 $postpone[ $linkTarget ] = $data[$linkName]; 631 $linkNames[ $linkTarget ] = $linkName; 632 } 591 633 } 592 634 } … … 609 651 $value = array( 'id' => $value ); 610 652 611 $value[ $URI['concept']] = $URI['id'];612 653 $value[ self::links( $URI['concept'], $linkNames[ $linkTarget ] ) ] = $URI['id']; 654 613 655 self::put( array( 'concept' => $linkTarget ), $value, &$txIds ); 614 656 } … … 658 700 659 701 Controller::$cache = Controller::loadCache(); 660 ?>702 // ?> -
trunk/prototype/api/datalayer.js
r5437 r5514 4 4 arrayName = /^([A-z0-9-_]+)\[\]$/; 5 5 startsDoubleDot = /^:/; 6 isIframe = /^iframe.*/; 7 FILE = 'files'; 6 8 // cached_urls = {}; 7 9 … … 13 15 // return; 14 16 // alert( options.url + " dentro" ); 15 jqXHR.abort(); 16 17 var callback = ( options.success || options.complete || $.noop ); 17 18 var callback = ( options.success || options.complete || $.noop ); 19 20 if( isIframe.test( options.dataType ) || options.data instanceof FormData ) 21 { 22 res = internalUrl.exec( options.url ); 23 24 var data = {}; 25 26 data[ res[1] ] = DataLayer.form( options.fileInput.parents( 'form' ), options.fileInput ); 27 28 options.formData = DataLayer.serializeForm( data ); 29 30 callback = function( data ){ 31 32 //coutinho, escreva seu codigo aqui. 33 34 return callback( DataLayer.encode( res[2], data ) ); 35 36 } 37 38 options.url = DataLayer.dispatchPath + 'post.php'; 39 40 if( options.data instanceof FormData ) 41 { 42 options.data = new FormData(); 43 44 $.each(options.formData, function (index, field) { 45 options.data.append(field.name, field.value); 46 }); 47 48 $.each(options.files, function (index, file) { 49 options.data.append(options.paramName, file); 50 }); 51 } 52 53 return( true ); 54 } 55 56 jqXHR.abort(); 18 57 19 58 switch( options.type.toUpperCase() ) … … 62 101 //TODO: check the type for conversion 63 102 DataLayer.receive, 64 false, { 'formData': $this.serializeArray(), 'fileInput': fileInputs } );103 false, { 'formData': $this.serializeArray(), 'fileInput': fileInputs, 'paramName': FILE + '[]' } ); 65 104 66 105 return( false ); … … 79 118 80 119 case 'POST': 81 DataLayer.put( res[1], data );120 DataLayer.put( res[1], data ); 82 121 } 83 122 … … 93 132 94 133 links: {}, 134 nestedLinks: {}, 95 135 concepts: {}, 96 136 listeners: {}, … … 216 256 }, 217 257 218 form: function( target ){219 220 var params = {}, $this = $(target) ;258 form: function( target, fileInputs ){ 259 260 var params = {}, $this = $(target), inputArray = $this.serializeArray(); 221 261 222 262 if( !$this.is( "form" ) ) 223 263 $this = $this.parents( "form" ); 224 225 $.each( $this.serializeArray(), function( i, el ){ 264 265 if( fileInputs ) 266 fileInputs.each( function( i, el ){ 267 268 inputArray[ inputArray.length ] = { name: $(this).prop("name"), value: FILE + i }; 269 270 }); 271 272 $.each( inputArray, function( i, el ){ 226 273 227 274 if( newName = arrayName.exec( el.name ) ) … … 242 289 return this.decode( $this.attr( "action" ), params ); 243 290 }, 291 292 serializeForm: function( data, level ){ 293 294 var formData = []; 295 296 for( key in data ) 297 { 298 var value = data[key]; 299 300 if( level !== undefined ) 301 key = level+'['+key+']'; 302 303 if( $.isArray(value) || $.isPlainObject(value) ) 304 formData = formData.concat( this.serializeForm( value, key ) ); 305 else 306 formData[ formData.length ] = { name: key, value: value }; 307 } 308 309 return( formData ); 310 }, 244 311 245 312 blend: function( action, data ){ … … 307 374 if( bothSides || !oneSide ) 308 375 { 309 var result = false, links = this.links( concept ), 376 var result = false, links = this.links( concept ), nestedLinks = this.links( concept, true ), 310 377 current = this.check( concept ) || {}, ids = []; 311 378 … … 333 400 el = { id: el }; 334 401 335 var nestedLinks = _this.links( links[link], true );336 402 //removido pois o mesmo esta gerando inconsistencia em tudo 403 // if( DataLayer.isConcept( links[link], nestedLinks[link] ) ) 337 404 if( isConcept ) 338 405 { 339 el[ nestedLinks[ concept] ] = el[ nestedLinks[concept] ] || [];340 el[ nestedLinks[ concept] ].push( key );406 el[ nestedLinks[link] ] = el[ nestedLinks[link] ] || []; 407 el[ nestedLinks[link] ].push( key ); 341 408 } 342 409 else 343 el[ nestedLinks[ concept] ] = key;410 el[ nestedLinks[link] ] = key; 344 411 345 412 if( isRef && ( !current[ key ] || !current[ key ][ link ] || … … 393 460 var bothSides = (typeof oneSide === "undefined"), 394 461 395 links = this.links( concept ), ids = [],462 links = this.links( concept ), nestedLinks = this.links( concept, true ), ids = [], 396 463 397 464 current = this.check( concept, id ); … … 399 466 if( !current ) return; 400 467 401 if( id)468 if( typeof id === "string" ) 402 469 current.id = id; 403 470 … … 420 487 continue; 421 488 422 var nestedLinks = this.links( links[link], true );423 424 489 if( isConcept = this.isConcept( concept, link ) ) 425 490 current[i][link] = [ current[i][link] ]; … … 429 494 el = DataLayer.storage.cache[links[link]][el]; 430 495 431 if( notArrayNested = ( $.type( el[ nestedLinks[ concept] ] ) !== "array" ) )432 el[ nestedLinks[ concept] ] = [ el[nestedLinks[concept]] ];433 434 el[ nestedLinks[ concept] ] = $.grep( el[ nestedLinks[concept] ], function( nested, iii ){496 if( notArrayNested = ( $.type( el[ nestedLinks[link] ] ) !== "array" ) ) 497 el[ nestedLinks[link] ] = [ el[nestedLinks[link]] ]; 498 499 el[ nestedLinks[link] ] = $.grep( el[ nestedLinks[link] ], function( nested, iii ){ 435 500 return ( currentId !== nested ); 436 501 }); 437 502 438 503 if( notArrayNested ) 439 el[ nestedLinks[ concept] ] = el[ nestedLinks[concept] ][0] || false;440 if(!el[ nestedLinks[ concept] ] || !el[ nestedLinks[concept] ].length)441 delete el[ nestedLinks[ concept] ];504 el[ nestedLinks[link] ] = el[ nestedLinks[link] ][0] || false; 505 if(!el[ nestedLinks[link] ] || !el[ nestedLinks[link] ].length) 506 delete el[ nestedLinks[link] ]; 442 507 }); 443 508 } … … 905 970 906 971 this.links[ concept ] = result['links'] || {}; 972 973 this.nestedLinks[ concept ] = result['nestedLinks'] || {}; 907 974 } 908 975 909 976 if( reverse ) 910 977 { 911 var reverted = {}, llinks = this.links[ concept ]; 912 913 for( var key in llinks ) 914 reverted[ llinks[key] ] = key; 915 916 return( reverted ); 978 return( this.nestedLinks[ concept ] ); 917 979 } 918 980 … … 1014 1076 1015 1077 if( result && bothSides && (!filter || 1016 1017 1078 !filter.criteria || 1079 !filter.criteria.format) ) 1018 1080 { 1019 1081 var newResult = []; … … 1032 1094 }, 1033 1095 1034 1035 filter: function( base, filter ){ 1096 filter: function( base, filter, criteria ){ 1036 1097 1098 if( !$.isArray( filter || [] ) ) 1099 filter = filter.filter || false; 1100 1101 if( !filter ) 1102 return( base ); 1103 1037 1104 var filtered = []; 1038 1105 1039 // var operator = filter.shift(); 1040 1041 /*for( var key in base ) 1042 { 1043 switch( operator ) 1044 { 1045 case 'AND': 1046 for( var i = 0, current = true; i < filter.length && current; i++ ) 1047 current = this.compare( '&', current, this.compare( base[key], filter[i] ) ); 1048 break; 1049 case 'OR': 1050 for( var i = 0, current = false; i < filter.length && !current; i++ ) 1051 current = this.compare( '|', current, this.compare( base[key], filter[i] ) ); 1052 break; 1053 case 'IN': 1054 for( var i = 0, current = false; i < filter[1].length && !current; i++ ) 1055 current = this.compare( '|', current, this.compare( base[key], [ '=', filter[0], filter[1][i] ] ) ); 1056 break; 1057 default : current = this.compare( operator, base[key], ); 1058 } 1059 */ 1060 // if( !noGroup ) 1061 // for( var i = 0, current = original; i < filter.length && ( current === original ); i++ ) 1062 // current = this.compare( operator, current, this.compare( base[key], filter[i] ) ); 1063 1064 // if( current ) 1065 // filtered[ filtered.length ] = key; 1066 // } 1106 for( var key in base ) 1107 if( this.storage.filter( base[key], filter ) ) 1108 filtered[ filtered.length ] = key; 1067 1109 1068 1110 return( filtered ); … … 1073 1115 switch( operator ) 1074 1116 { 1075 case '*': return RegExp( "*" + base + "*" ).test( test);1076 case '^': return RegExp( "^" + base + "" ).test( test);1077 case '$': return RegExp( "" + base + "$" ).test( test);1078 1079 case '&': return ( base && test );1080 case '|': return ( base || test );1117 case '*': return RegExp( ".*" + test + ".*" ).test( base ); 1118 case '^': return RegExp( "^" + test + ".*" ).test( base ); 1119 case '$': return RegExp( ".*" + test + "$" ).test( base ); 1120 1121 case '&': return ( base && test ); 1122 case '|': return ( base || test ); 1081 1123 1082 1124 case '=': return ( base == test ); … … 1095 1137 // }, 1096 1138 1097 check: function( namespace, keys){1139 check: function( namespace, filter ){ 1098 1140 1099 1141 if( !namespace ) … … 1102 1144 var result = this.storage.get( namespace ); 1103 1145 1104 if( ! keys|| !result )1146 if( !filter || !result ) 1105 1147 return( result || false ); 1148 1149 var keys = DataLayer.copy( filter ); 1106 1150 1107 1151 if( notArray = $.type(keys) === "string" ) 1108 1152 keys = [ keys ]; 1109 1153 else if( $.type(keys) !== "array" ) 1110 keys = this.filter( result, keys.filter);1154 keys = this.filter( result, keys.filter, keys.criteria ); 1111 1155 1112 1156 var res = []; … … 1136 1180 delete this.cache[key]; 1137 1181 1182 }, 1183 1184 filter: function( base, filter ){ 1185 1186 var bool, op = filter.shift(); 1187 1188 switch( op ) 1189 { 1190 case 'IN': 1191 for( var i = 0, f = []; i < filter[1].length || !(filter = f); i++ ) 1192 f[i] = [ '=', filter[0], filter[1][i] ]; 1193 case 'OR': 1194 op = '|'; 1195 bool = false; 1196 break; 1197 case 'AND': 1198 op = '&'; 1199 bool = true; 1200 break; 1201 default : return DataLayer.compare( op, base[ filter[0] ], filter[1] ); 1202 } 1203 1204 for( var strict = bool; 1205 1206 filter.length && ( strict ? bool : !bool ); 1207 1208 bool = DataLayer.compare( op, bool, this.filter( base, filter.shift() ) ) ); 1209 1210 return( bool ); 1138 1211 } 1139 1212 }, … … 2431 2504 // } 2432 2505 // } 2506 2507 // internalUrl = /^([A-z0-9-_]+)(:[A-z0-9-_]+)?$/; 2508 // internalUri = /^([a-zA-Z0-9-_]+)\(([a-zA-Z0-9-_]+)\):\/\/(.*)|([a-zA-Z0-9-_]+):\/\/(.*)$/; 2509 // isGeneratedId = /^\d+\(javascript\)$/; 2510 // arrayName = /^([A-z0-9-_]+)\[\]$/; 2511 // startsDoubleDot = /^:/; 2512 // FILE = 'files'; 2513 // // cached_urls = {}; 2514 // 2515 // $.ajaxPrefilter(function( options, originalOptions, jqXHR ){ 2516 // 2517 // if( options.url != 'undefined' && internalUrl.test( options.url ) ){ 2518 // 2519 // // if( !cached_urls[options.url] ) 2520 // // return; 2521 // // alert( options.url + " dentro" ); 2522 // jqXHR.abort(); 2523 // 2524 // var callback = ( options.success || options.complete || $.noop ); 2525 // 2526 // switch( options.type.toUpperCase() ) 2527 // { 2528 // case 'GET': 2529 // return callback( DataLayer.get( options.url, /*false,*/ options.data ) ); 2530 // 2531 // case 'POST': 2532 // return callback( DataLayer.put( options.url, options.data ) ); 2533 // } 2534 // 2535 // //return( false ); 2536 // 2537 // // options.url = params[1]; 2538 // // options.data = ( options.data || "" ) + "&" + params[2]; 2539 // } 2540 // 2541 // }); 2542 // 2543 // // $("a").live("click", function( event ){ 2544 // // 2545 // // event.preventDefault(); 2546 // // 2547 // // $.ajax({ 2548 // // 2549 // // 2550 // // 2551 // // }); 2552 // // 2553 // // }); 2554 // 2555 // $("form").live( "submit", function( event ){ 2556 // 2557 // var $this = $(this), action = $this.attr('action'), res = false, 2558 // 2559 // method = $this.attr( 'method' ), 2560 // 2561 // fileInputs = $this.find('input[type="file"]'); 2562 // 2563 // if( fileInputs.length && !$this.is('[enctype="multipart/form-data"]') ) 2564 // { 2565 // event.preventDefault(); 2566 // 2567 // var formData = $this.serializeArray(), callback = DataLayer.receive; 2568 // 2569 // if( res = internalUrl.exec( action ) ) 2570 // { 2571 // var data = {}, action = res[1]; 2572 // 2573 // data[action] = DataLayer.form( this, fileInputs ); 2574 // 2575 // formData = DataLayer.serializeForm( data ); 2576 // 2577 // action = DataLayer.dispatchPath + 'post.php'; 2578 // callback = $.noop; 2579 // } 2580 // 2581 // DataLayer.send( action, 2582 // [ method, 'iframe json' ], {}, 2583 // //TODO: check the type for conversion 2584 // callback, 2585 // false, { 'formData': formData, 'fileInput': fileInputs, 'paramName': FILE + '[]' } ); 2586 // 2587 // return( false ); 2588 // } 2589 // 2590 // if( res = internalUrl.exec( action ) ) 2591 // { 2592 // event.preventDefault(); 2593 // 2594 // var data = DataLayer.form( this ); 2595 // 2596 // switch( method.toUpperCase() ) 2597 // { 2598 // case 'GET': 2599 // DataLayer.get( res[0], data ); 2600 // 2601 // case 'POST': 2602 // DataLayer.put( res[1], data ); 2603 // } 2604 // 2605 // return( false ); 2606 // } 2607 // 2608 // return( true ); 2609 // }); 2610 // 2611 // this.storage = new $.store(); 2612 // 2613 // DataLayer = { 2614 // 2615 // links: {}, 2616 // concepts: {}, 2617 // listeners: {}, 2618 // encoders: {}, 2619 // decoders: {}, 2620 // templates: {}, 2621 // criterias: {}, 2622 // tasks: [], 2623 // 2624 // render: function( templateName, data, filter, formatter, force ){ 2625 // 2626 // if( $.isFunction( filter ) ) 2627 // { 2628 // force = formatter; 2629 // formatter = filter; 2630 // filter = false; 2631 // } 2632 // 2633 // if( typeof data === "string" ) 2634 // { 2635 // data = this.get( data, filter, force ) || {}; 2636 // } 2637 // 2638 // var formatting = function( template ){ 2639 // 2640 // if( template === false ) return( false ); 2641 // 2642 // if( template ) 2643 // DataLayer.templates[ templateName ] = new EJS({ text: template, cache: false }); 2644 // 2645 // var html = DataLayer.templates[ templateName ].render( { data: data } ); 2646 // 2647 // if( !formatter ) 2648 // return( html ); 2649 // 2650 // return formatter( html ); 2651 // } 2652 // 2653 // if( this.templates[ templateName ] ) 2654 // { 2655 // return formatting(); 2656 // } 2657 // 2658 // return this.send( DataLayer.templatePath + templateName, 'get', false, formatting, !!!formatter ); 2659 // }, 2660 // 2661 // send: function( url, type, data, callback, sync, extraOptions ){ 2662 // 2663 // var result = false, fired = false; 2664 // 2665 // var envelope = { 2666 // 2667 // 'async': ( typeof sync !== "undefined" ? !sync : !!callback ), 2668 // 'url': url, 2669 // 'success': function( dt, textStatus, jqXHR ){ 2670 // 2671 // if( callback ) 2672 // { 2673 // fired = true; 2674 // result = callback( dt, textStatus, jqXHR ); 2675 // } 2676 // else 2677 // result = dt; 2678 // 2679 // }, 2680 // 'complete': function( jqXHR, textStatus ){ 2681 // 2682 // if( !fired && callback ) 2683 // result = callback( false, textStatus, jqXHR ); 2684 // 2685 // }, 2686 // 2687 // 'type': $.isArray( type ) ? type[0] : type, 2688 // 'data': data 2689 // 2690 // }; 2691 // 2692 // if( $.isArray( type ) && type[1] ) 2693 // envelope['dataType'] = type[1]; 2694 // 2695 // if( extraOptions ) 2696 // envelope = $.extend( envelope, extraOptions ); 2697 // 2698 // $.ajax( envelope ); 2699 // 2700 // return( result ); 2701 // }, 2702 // 2703 // dispatch: function( dispatcher, data, callback, isPost, dataType ){ 2704 // 2705 // return this.send( this.dispatchPath + dispatcher + ".php", 2706 // [ ( isPost ? 'post' : 'get' ), dataType || 'json' ], 2707 // data, 2708 // callback ); 2709 // 2710 // // $.ajax({ 2711 // // 'async': !!callback, 2712 // // 'url': this.dispatchPath + dispatcher + ".php", 2713 // // 'type': ( isPost ? 'post' : 'get' ), 2714 // // 'dataType': 'json', 2715 // // 'data': data, 2716 // // 'success': function( dt, textStatus, jqXHR ){ 2717 // // 2718 // // if( callback ) 2719 // // { 2720 // // fired = true; 2721 // // callback( dt, textStatus, jqXHR ); 2722 // // } 2723 // // else 2724 // // result = dt; 2725 // // 2726 // // }, 2727 // // 'complete': function( jqXHR, textStatus ){ 2728 // // 2729 // // if( !fired && callback ) 2730 // // callback( false, textStatus, jqXHR ); 2731 // // 2732 // // }/*, 2733 // // 'processData': false*/ 2734 // // }); 2735 // 2736 // //return( result ); 2737 // }, 2738 // 2739 // form: function( target, fileInputs ){ 2740 // 2741 // var params = {}, $this = $(target), inputArray = $this.serializeArray(); 2742 // 2743 // if( !$this.is( "form" ) ) 2744 // $this = $this.parents( "form" ); 2745 // 2746 // if( fileInputs ) 2747 // fileInputs.each( function( i, el ){ 2748 // 2749 // inputArray[ inputArray.length ] = { name: $(this).prop("name"), value: FILE + i }; 2750 // 2751 // }); 2752 // 2753 // $.each( inputArray, function( i, el ){ 2754 // 2755 // if( newName = arrayName.exec( el.name ) ) 2756 // el.name = newName[1]; 2757 // else if( !params[ el.name ] ) 2758 // return( params[ el.name ] = el.value ); 2759 // 2760 // params[ el.name ] = params[ el.name ] || []; 2761 // 2762 // if( $.type(params[ el.name ]) !== "array" ) 2763 // params[ el.name ] = [ params[ el.name ] ]; 2764 // 2765 // params[ el.name ].push( el.value ); 2766 // }); 2767 // 2768 // // alert(dump(params)); 2769 // 2770 // return this.decode( $this.attr( "action" ), params ); 2771 // }, 2772 // 2773 // serializeForm: function( data, level ){ 2774 // 2775 // var formData = []; 2776 // 2777 // for( key in data ) 2778 // { 2779 // var value = data[key]; 2780 // 2781 // if( level !== undefined ) 2782 // key = level+'['+key+']'; 2783 // 2784 // if( $.isArray(value) || $.isPlainObject(value) ) 2785 // formData = formData.concat( this.serializeForm( value, key ) ); 2786 // else 2787 // formData[ formData.length ] = { name: key, value: value }; 2788 // } 2789 // 2790 // return( formData ); 2791 // }, 2792 // 2793 // blend: function( action, data ){ 2794 // 2795 // // if( notArray = (!$.isArray(data)) ) 2796 // // data = [ data ]; 2797 // 2798 // var form = $('form[action="'+action+'"]'); 2799 // 2800 // form.get(0).reset(); 2801 // 2802 // var named = form.find( 'input[name]' ); 2803 // 2804 // for( var name in data ) 2805 // { 2806 // named.filter( '[name="'+name+'"]' ).val( data[name] ); 2807 // } 2808 // }, 2809 // 2810 // 2811 // 2812 // put: function( concept, filter, data, oneSide ){ 2813 // 2814 // ///////////////////////////// normalize //////////////////////////////// 2815 // if( arguments.length == 2 ) 2816 // { 2817 // data = filter; 2818 // filter = false; 2819 // } 2820 // if( typeof data === "undefined" || 2821 // $.type(data) === "boolean" ) 2822 // { 2823 // oneSide = data; 2824 // data = filter; 2825 // filter = false; 2826 // } 2827 // 2828 // if( !concept || !data ) 2829 // return( false ); 2830 // 2831 // var decoder = "", id = false, bothSides = (typeof oneSide === "undefined"), notArray, res; 2832 // 2833 // if( $.type(filter) === "string" ) 2834 // { 2835 // id = filter; 2836 // filter = false; 2837 // } 2838 // 2839 // if( id ) 2840 // data.id = id; 2841 // 2842 // if( notArray = ( $.type( data ) !== "array" ) ) 2843 // data = [ data ]; 2844 // 2845 // if( res = internalUrl.exec( concept ) ) 2846 // { 2847 // //TODO: verificar se a decodificaçao deve ser feita em cada item do array 2848 // data = this.decode( concept, data ); 2849 // concept = res[1]; 2850 // decoder = res[2]; 2851 // } 2852 // 2853 // //////////////////////////////////////////////////////////////////////// 2854 // 2855 // if( bothSides || !oneSide ) 2856 // { 2857 // var result = false, links = this.links( concept ), 2858 // current = this.check( concept ) || {}, ids = []; 2859 // 2860 // for( var i = 0; i < data.length; i++ ) 2861 // { 2862 // var key = ids[ ids.length ] = data[i].id || this.generateId( concept ), updateSet = {}; 2863 // 2864 // ////////////////////////////// linkage ///////////////////////////////// 2865 // for( var link in links ) 2866 // { 2867 // if( data[i][link] ) 2868 // { 2869 // var isConcept = false; 2870 // 2871 // if( isConcept = this.isConcept( concept, link ) ) 2872 // data[i][link] = [ data[i][link] ]; 2873 // 2874 // var _this = this; 2875 // 2876 // $.each( data[i][link], function( ii, el ){ 2877 // 2878 // var isRef = false; 2879 // 2880 // if( isRef = ($.type(el) === "string") ) 2881 // el = { id: el }; 2882 // 2883 // var nestedLinks = _this.links( links[link], true ); 2884 // //removido pois o mesmo esta gerando inconsistencia em tudo 2885 // //if( DataLayer.isConcept( links[link], nestedLinks[concept] ) ) 2886 // if( isConcept ) 2887 // { 2888 // el[ nestedLinks[link] ] = el[ nestedLinks[link] ] || []; 2889 // el[ nestedLinks[link] ].push( key ); 2890 // } 2891 // else 2892 // el[ nestedLinks[link] ] = key; 2893 // 2894 // if( isRef && ( !current[ key ] || !current[ key ][ link ] || 2895 // (isConcept ? current[ key ][ link ] !== el.id : !$.inArray( el.id, current[ key ][ link ] )) ) ) 2896 // { 2897 // updateSet[ links[link] ] = updateSet[ links[link] ] || []; 2898 // updateSet[ links[link] ].push( el ); 2899 // } 2900 // else if( !isRef ) 2901 // data[i][link][ii] = _this.put( links[link], el, oneSide ); 2902 // }); 2903 // 2904 // if( isConcept ) 2905 // data[i][link] = data[i][link][0]; 2906 // } 2907 // } 2908 // ////////////////////////////////////////////////////////////////////////// 2909 // 2910 // if( data[i].id ) 2911 // data[i] = this.merge( current[ data[i].id ], data[i] ); 2912 // 2913 // current[ key ] = data[i]; 2914 // 2915 // if( bothSides ) 2916 // this.report( concept, key, data[i] ); 2917 // } 2918 // 2919 // this.store( concept, current ); 2920 // 2921 // for( var setKey in updateSet ) 2922 // { 2923 // if( bothSides ) 2924 // for( var i = 0; i < updateSet[ setKey ].length; i++ ) 2925 // this.report( setKey, updateSet[ setKey ][i].id, updateSet[ setKey ][i] ); 2926 // 2927 // DataLayer.put( setKey, updateSet[ setKey ], false ); 2928 // } 2929 // } 2930 // 2931 // if( oneSide ) 2932 // this.commit( concept, ids/*, true */); 2933 // 2934 // this.broadcast( concept, oneSide ? 'server' : bothSides ? 'serverclient' : 'client', true ); 2935 // 2936 // return( notArray ? ids[0] : ids ); 2937 // 2938 // }, 2939 // 2940 // remove: function( concept, id, oneSide ){ 2941 // 2942 // var bothSides = (typeof oneSide === "undefined"), 2943 // 2944 // links = this.links( concept ), ids = [], 2945 // 2946 // current = this.check( concept, id ); 2947 // 2948 // if( !current ) return; 2949 // 2950 // if( id ) 2951 // current.id = id; 2952 // 2953 // if( notArray = ( $.type( current ) !== "array" ) ) 2954 // current = [ current ]; 2955 // 2956 // for( var i = 0; i < current.length; i++ ) 2957 // { 2958 // var currentId = ids[ ids.length ] = current[i].id; 2959 // 2960 // if( bothSides ) 2961 // this.report( concept, currentId, false ); 2962 // 2963 // if( bothSides || !oneSide ) 2964 // this.del( concept, currentId ); 2965 // 2966 // for( var link in links ) 2967 // { 2968 // if( !current[i][link] ) 2969 // continue; 2970 // 2971 // var nestedLinks = this.links( links[link], true ); 2972 // 2973 // if( isConcept = this.isConcept( concept, link ) ) 2974 // current[i][link] = [ current[i][link] ]; 2975 // 2976 // $.each( current[i][link], function( ii, el ){ 2977 // 2978 // el = DataLayer.storage.cache[links[link]][el]; 2979 // 2980 // if( notArrayNested = ( $.type( el[ nestedLinks[link] ] ) !== "array" ) ) 2981 // el[ nestedLinks[link] ] = [ el[nestedLinks[link]] ]; 2982 // 2983 // el[ nestedLinks[link] ] = $.grep( el[ nestedLinks[link] ], function( nested, iii ){ 2984 // return ( currentId !== nested ); 2985 // }); 2986 // 2987 // if( notArrayNested ) 2988 // el[ nestedLinks[link] ] = el[ nestedLinks[link] ][0] || false; 2989 // if(!el[ nestedLinks[link] ] || !el[ nestedLinks[link] ].length) 2990 // delete el[ nestedLinks[link] ]; 2991 // }); 2992 // } 2993 // } 2994 // 2995 // if( oneSide ) 2996 // this.commit( concept, ids ); 2997 // 2998 // this.broadcast( concept, oneSide ? 'server' : bothSides ? 'serverclient' : 'client', false ); 2999 // }, 3000 // 3001 // report: function( concept, id, data ) 3002 // { 3003 // var current = this.check( ':current', concept ) || {}; 3004 // 3005 // if( !current[ id ] ) 3006 // current[ id ] = this.check( concept, id ) || {}; 3007 // 3008 // this.store( ':current', concept, current ); 3009 // 3010 // var diff = this.diff( current[ id ], data ); 3011 // 3012 // var diffs = this.check( ':diff', concept ) || {}; 3013 // 3014 // if( diffs[ id ] ) 3015 // diff = this.merge( diffs[ id ], diff ); 3016 // 3017 // if( !diff || !$.isEmptyObject( diff ) ) 3018 // diffs[ id ] = diff; 3019 // 3020 // this.store( ':diff', concept, diffs ); 3021 // }, 3022 // 3023 // // enqueue: function( queueName, concept, id, data ){ 3024 // // 3025 // // var queue = this.check( ':' + queueName, concept ) || {}; 3026 // // 3027 // // 3028 // // }, 3029 // // 3030 // // dequeue: function( queueName, concept, id ){ 3031 // // 3032 // // 3033 // // 3034 // // }, 3035 // 3036 // 3037 // 3038 // rollback: function( concept, ids ){ 3039 // 3040 // var queue = this.prepareQ( 'current', concept, ids ); 3041 // 3042 // ids = []; 3043 // 3044 // for( var id in queue ) 3045 // { 3046 // this.put( concept, id, queue[id], false ); 3047 // 3048 // ids[ ids.length ] = id; 3049 // } 3050 // 3051 // this.clearQ( concept, ( ids.length ? ids : false ) ); 3052 // 3053 // this.broadcast( concept, 'revert' ); 3054 // 3055 // }, 3056 // 3057 // prepareQ: function( queueName, concept, ids ){ 3058 // 3059 // var notArray = false; 3060 // 3061 // if( notArray = ($.type(concept) !== "array") ) 3062 // concept = [ concept ]; 3063 // 3064 // var q = {}; 3065 // 3066 // for( var i = 0; i < concept.length; i++ ) 3067 // { 3068 // var queue = this.check( ':' + queueName, concept[i] || false ); 3069 // 3070 // if( !queue ) continue; 3071 // 3072 // if( ids ) 3073 // { 3074 // if( $.type(ids) !== "array" ) 3075 // ids = [ ids ]; 3076 // 3077 // var filtered = {}; 3078 // 3079 // for( var ii = 0; ii < ids.length; ii++ ) 3080 // { 3081 // filtered[ ids[ii] ] = queue[ ids[ii] ]; 3082 // } 3083 // 3084 // queue = filtered; 3085 // } 3086 // 3087 // q[ concept[i] ] = queue; 3088 // } 3089 // 3090 // return( notArray ? q[ concept[0] ] : q ); 3091 // }, 3092 // 3093 // clearQ: function( concept, ids ){ 3094 // 3095 // var current = this.check( ':current', concept || false ); 3096 // var diffs = this.check( ':diff', concept || false ); 3097 // 3098 // if( !ids ) 3099 // current = diffs = {}; 3100 // else 3101 // { 3102 // if( notArray = ($.type(ids) !== "array") ) 3103 // ids = [ ids ]; 3104 // 3105 // for( var i = 0; i < ids.length; i++ ) 3106 // { 3107 // delete current[ ids[i] ]; 3108 // delete diffs[ ids[i] ]; 3109 // } 3110 // } 3111 // 3112 // this.store( ':current', concept, current ); 3113 // this.store( ':diff', concept, diffs ); 3114 // }, 3115 // 3116 // commit: function( concept, ids, callback ){ 3117 // 3118 // var queue = this.prepareQ( 'diff', concept, ids ); 3119 // 3120 // this.sync( queue, !$.isArray(concept) && concept || false, callback ); 3121 // }, 3122 // 3123 // sync: function( queue, concept, callback ){ 3124 // 3125 // if( !queue || $.isEmptyObject( queue ) ) 3126 // return; 3127 // 3128 // if( concept ) 3129 // { 3130 // var helper = {}; 3131 // helper[concept] = queue; 3132 // queue = helper; 3133 // } 3134 // 3135 // var data = {}, URIs = {}; 3136 // 3137 // for( var concept in queue ) 3138 // for( var id in queue[concept] ) 3139 // { 3140 // data[ this.URI( concept, id ) ] = queue[concept][id]; 3141 // URIs[ this.URI( concept, id ) ] = { concept: concept, id: id }; 3142 // } 3143 // 3144 // if( $.isEmptyObject( data ) ) 3145 // return; 3146 // 3147 // this.dispatch( "Sync", data, function( data, status, jqXHR ){ 3148 // 3149 // // switch( status ) 3150 // // { 3151 // // case "error": 3152 // // case "parsererror": 3153 // // return DataLayer.rollback( concept, URI ); 3154 // // case "success": 3155 // // return DataLayer.commit(); 3156 // // case "timeout": 3157 // // case "notmodified": 3158 // // } 3159 // 3160 // var received = DataLayer.receive( data ); 3161 // 3162 // for( var URI in URIs ) 3163 // if( typeof received[URI] !== "undefined" ) 3164 // DataLayer.clearQ( URIs[URI].concept, URIs[URI].id ); 3165 // 3166 // if( callback ) 3167 // callback( received ); 3168 // 3169 // // for( var URI in data ) 3170 // // { 3171 // // var parsed = DataLayer.parseURI( URI ), 3172 // // 3173 // // concept = parsed[1], id = parsed[3]; 3174 // // 3175 // // if( $.type(data[URI]) === "string" ) 3176 // // { 3177 // // //TODO:threat the exception thrown 3178 // // DataLayer.rollback( concept, id ); 3179 // // delete URIs[ URI ]; 3180 // // continue; 3181 // // } 3182 // // 3183 // // if( data[URI] === false ){ 3184 // // DataLayer.remove( concept, id, false ); 3185 // // continue; 3186 // // } 3187 // // 3188 // // if( id !== data[URI].id ) 3189 // // DataLayer.move( concept, id, data[URI].id ); 3190 // // 3191 // // DataLayer.put( concept, id, data[URI], false ); 3192 // // } 3193 // // 3194 // // for( var URI in URIs ) 3195 // // DataLayer.clearQ( URIs[URI].concept, URIs[URI].id ); 3196 // // 3197 // // if( callback ) 3198 // // callback(); 3199 // 3200 // }, true ); 3201 // 3202 // }, 3203 // 3204 // receive: function( data ){ 3205 // 3206 // var received = {}; 3207 // 3208 // for( var URI in data ) 3209 // { 3210 // var parsed = DataLayer.parseURI( URI ), 3211 // 3212 // concept = parsed[4], id = parsed[5]; 3213 // 3214 // received[ URI ] = data[ URI ]; 3215 // 3216 // if( $.type(data[URI]) === "string" ) 3217 // { 3218 // //TODO:threat the exception thrown 3219 // DataLayer.rollback( concept, id ); 3220 // continue; 3221 // } 3222 // 3223 // if( data[URI] === false ){ 3224 // DataLayer.remove( concept, id, false ); 3225 // continue; 3226 // } 3227 // 3228 // if( id !== data[URI].id ) 3229 // DataLayer.move( concept, id, data[URI].id ); 3230 // 3231 // DataLayer.put( concept, id, data[URI], false ); 3232 // } 3233 // 3234 // return( received ); 3235 // 3236 // }, 3237 // 3238 // unique: function( origArr ){ 3239 // 3240 // var newArr = []; 3241 // 3242 // for ( var x = 0; x < origArr.length; x++ ) 3243 // { 3244 // var found = false; 3245 // for ( var y = 0; !found && y < newArr.length; y++ ) 3246 // if ( origArr[x] === newArr[y] ) 3247 // found = true; 3248 // 3249 // if ( !found ) 3250 // newArr[ newArr.length ] = origArr[x]; 3251 // } 3252 // 3253 // return newArr; 3254 // }, 3255 // 3256 // merge: function( current, data ){ 3257 // 3258 // return this.copy( data, current ); 3259 // 3260 // // return $.extend( current, data ); 3261 // 3262 // }, 3263 // 3264 // // clone objects, skip other types. 3265 // clone: function(target) { 3266 // if ( typeof target == 'object' ) { 3267 // Clone.prototype = target; 3268 // return new Clone(); 3269 // } else { 3270 // return target; 3271 // } 3272 // }, 3273 // 3274 // // Shallow Copy 3275 // shallowCopy: function(target) { 3276 // if (typeof target !== 'object' ) { 3277 // return target; // non-object have value sematics, so target is already a copy. 3278 // } else { 3279 // var value = target.valueOf(); 3280 // if (target != value) { 3281 // // the object is a standard object wrapper for a native type, say String. 3282 // // we can make a copy by instantiating a new object around the value. 3283 // return new target.constructor(value); 3284 // } else { 3285 // // ok, we have a normal object. If possible, we'll clone the original's prototype 3286 // // (not the original) to get an empty object with the same prototype chain as 3287 // // the original. If just copy the instance properties. Otherwise, we have to 3288 // // copy the whole thing, property-by-property. 3289 // if ( target instanceof target.constructor && target.constructor !== Object ) { 3290 // var c = clone(target.constructor.prototype); 3291 // 3292 // // give the copy all the instance properties of target. It has the same 3293 // // prototype as target, so inherited properties are already there. 3294 // for ( var property in target) { 3295 // if (target.hasOwnProperty(property)) { 3296 // c[property] = target[property]; 3297 // } 3298 // } 3299 // } else { 3300 // var c = {}; 3301 // for ( var property in target ) c[property] = target[property]; 3302 // } 3303 // 3304 // return c; 3305 // } 3306 // } 3307 // }, 3308 // 3309 // // entry point for deep copy. 3310 // // source is the object to be deep copied. 3311 // // depth is an optional recursion limit. Defaults to 256. 3312 // // deep copy handles the simple cases itself: non-objects and object's we've seen before. 3313 // // For complex cases, it first identifies an appropriate DeepCopier, then delegate the details of copying the object to him. 3314 // copy: function(source, result, depth) { 3315 // 3316 // // null is a special case: it's the only value of type 'object' without properties. 3317 // if ( source === null ) return null; 3318 // 3319 // // All non-objects use value semantics and don't need explict copying. 3320 // if ( typeof source !== 'object' ) return source; 3321 // 3322 // if( !depth || !(depth instanceof RecursionHelper) ) depth = new RecursionHelper(depth); 3323 // 3324 // var cachedResult = depth.getCachedResult(source); 3325 // 3326 // // we've already seen this object during this deep copy operation 3327 // // so can immediately return the result. This preserves the cyclic 3328 // // reference structure and protects us from infinite recursion. 3329 // if ( cachedResult ) return cachedResult; 3330 // 3331 // // objects may need special handling depending on their class. There is 3332 // // a class of handlers call "DeepCopiers" that know how to copy certain 3333 // // objects. There is also a final, generic deep copier that can handle any object. 3334 // for ( var i=0; i<this.comparators.length; i++ ) { 3335 // 3336 // var comparator = this.comparators[i]; 3337 // 3338 // if ( comparator.can(source) ) { 3339 // 3340 // // once we've identified which DeepCopier to use, we need to call it in a very 3341 // // particular order: create, cache, populate. This is the key to detecting cycles. 3342 // // We also keep track of recursion depth when calling the potentially recursive 3343 // // populate(): this is a fail-fast to prevent an infinite loop from consuming all 3344 // // available memory and crashing or slowing down the browser. 3345 // 3346 // if( !result ) 3347 // // Start by creating a stub object that represents the copy. 3348 // result = comparator.create(source); 3349 // else if( !comparator.can(result) ) 3350 // throw new Error("can't compare diferent kind of objects."); 3351 // 3352 // // we now know the deep copy of source should always be result, so if we encounter 3353 // // source again during this deep copy we can immediately use result instead of 3354 // // descending into it recursively. 3355 // depth.cacheResult(source, result); 3356 // 3357 // // only DeepCopier.populate() can recursively deep copy. So, to keep track 3358 // // of recursion depth, we increment this shared counter before calling it, 3359 // // and decrement it afterwards. 3360 // depth.depth++; 3361 // if ( depth.depth > depth.maxDepth ) { 3362 // throw new Error("Exceeded max recursion depth in deep copy."); 3363 // } 3364 // 3365 // // It's now safe to let the comparator recursively deep copy its properties. 3366 // var returned = comparator.populate( function(source, result) { return DataLayer.copy(source, result, depth); }, source, result ); 3367 // 3368 // if(returned) 3369 // result = returned; 3370 // 3371 // depth.depth--; 3372 // 3373 // return result; 3374 // } 3375 // } 3376 // // the generic copier can handle anything, so we should never reach this line. 3377 // throw new Error("no DeepCopier is able to copy " + source); 3378 // }, 3379 // 3380 // // publicly expose the list of deepCopiers. 3381 // comparators: [], 3382 // 3383 // // make deep copy() extensible by allowing others to 3384 // // register their own custom Comparators. 3385 // registerComparator: function(comparatorOptions) { 3386 // 3387 // // publicly expose the Comparator class. 3388 // var comparator = { 3389 // 3390 // // determines if this Comparator can handle the given object. 3391 // can: function(source) { return false; }, 3392 // 3393 // // starts the deep copying process by creating the copy object. You 3394 // // can initialize any properties you want, but you can't call recursively 3395 // // into the copy(). 3396 // create: function(source) { }, 3397 // 3398 // // Completes the deep copy of the source object by populating any properties 3399 // // that need to be recursively deep copied. You can do this by using the 3400 // // provided deepCopyAlgorithm instance's copy() method. This will handle 3401 // // cyclic references for objects already deepCopied, including the source object 3402 // // itself. The "result" passed in is the object returned from create(). 3403 // populate: function(deepCopyAlgorithm, source, result) {} 3404 // }; 3405 // 3406 // for ( var key in comparatorOptions ) comparator[key] = comparatorOptions[key]; 3407 // 3408 // this.comparators.unshift( comparator ); 3409 // }, 3410 // 3411 // diff: function( base, toDiff ){ 3412 // 3413 // if( typeof base === 'undefined' || $.isEmptyObject(base) ) 3414 // return( toDiff ); 3415 // 3416 // if( toDiff === false ) 3417 // return( false ); 3418 // 3419 // toDiff = $.extend( {}, toDiff ); 3420 // 3421 // for( var key in toDiff ) 3422 // { 3423 // switch( $.type(toDiff[key]) ) 3424 // { 3425 // case 'object': 3426 // if( $.isEmptyObject(toDiff[key] = this.diff( base[key], toDiff[key] )) ) 3427 // delete toDiff[key]; 3428 // break; 3429 // case 'array': 3430 // if( base[key] && !(toDiff[key] = $.grep( toDiff[key], function( el, i ){ return( $.inArray( el, base[key] ) === -1 ); } )).length ) 3431 // delete toDiff[key]; 3432 // break; 3433 // default: 3434 // if( base[key] == toDiff[key] ) 3435 // delete toDiff[key]; 3436 // } 3437 // } 3438 // 3439 // return( toDiff ); 3440 // 3441 // }, 3442 // 3443 // links: function( concept, reverse ){ 3444 // 3445 // if( !this.links[ concept ] ) 3446 // { 3447 // var result = this.dispatch( "links", { concept: concept } ) || false; 3448 // 3449 // if( !result ) 3450 // return( false ); 3451 // 3452 // this.concepts[ concept ] = $.extend( this.concepts[ concept ] || {}, 3453 // result['concepts'] || {} ); 3454 // 3455 // this.links[ concept ] = result['links'] || {}; 3456 // this.nestedLinks[ concept ] = result['nestedLinks'] || {}; 3457 // } 3458 // 3459 // if( reverse ) 3460 // { 3461 // return( this.nestedLinks[ concept ] ); 3462 // // var reverted = {}, llinks = this.links[ concept ]; 3463 // // 3464 // // for( var key in llinks ) 3465 // // reverted[ llinks[key] ] = key; 3466 // // 3467 // // return( reverted ); 3468 // } 3469 // 3470 // return( this.links[ concept ] ); 3471 // 3472 // }, 3473 // 3474 // isConcept: function( concept, attr ){ 3475 // 3476 // if( typeof this.concepts[concept] === "undefined" ) 3477 // { 3478 // this.links( concept ); 3479 // } 3480 // 3481 // return !!this.concepts[ concept ][ attr ]; 3482 // }, 3483 // 3484 // URI: function( concept, URI, context ){ 3485 // 3486 // if( res = internalUrl.exec( concept ) ) 3487 // concept = res[1]; 3488 // 3489 // context = context ? "(" + context + ")" : ""; 3490 // 3491 // if( URI ) 3492 // return( concept + context + "://" + URI ); 3493 // else 3494 // return( concept ); 3495 // 3496 // }, 3497 // 3498 // parseURI: function( URI ){ 3499 // 3500 // return internalUri.exec( URI ) || false; 3501 // 3502 // }, 3503 // 3504 // 3505 // 3506 // 3507 // generateId: function( concept ){ 3508 // 3509 // var newId = this.counter + "(javascript)"; 3510 // 3511 // this.store( ":counter", (this.counter++) + "" ); 3512 // 3513 // return( newId ); 3514 // }, 3515 // 3516 // 3517 // 3518 // 3519 // get: function( concept, /*URI, */filter, oneSide ){ 3520 // 3521 // ///////////////////////////// normalize //////////////////////////////// 3522 // if( arguments.length == 2 && $.type(filter) === "boolean" ) 3523 // { 3524 // oneSide = filter; 3525 // filter = false; 3526 // } 3527 // 3528 // var encoder = false, id = false, bothSides = (typeof oneSide === 'undefined'), res; 3529 // 3530 // if( $.type(filter) === "string" ) 3531 // { 3532 // id = filter; 3533 // filter = false; 3534 // } 3535 // 3536 // filter = filter || false; 3537 // 3538 // if( !concept ) 3539 // return( false ); 3540 // 3541 // if( res = internalUrl.exec( concept ) ) 3542 // { 3543 // encoder = concept; 3544 // concept = res[1]; 3545 // 3546 // if( filter ) 3547 // filter = this.criteria( encoder, filter ); 3548 // } 3549 // 3550 // if ( $.type(filter) === "array" ) 3551 // { 3552 // filter = { filter: filter, criteria: false }; 3553 // } 3554 // 3555 // ////////////////////////////////////////////////////////////////////////// 3556 // 3557 // var result = false; 3558 // 3559 // if( bothSides || !oneSide ) 3560 // result = this.check( concept, id || filter ); 3561 // 3562 // if( !result && (bothSides || oneSide) ) 3563 // { 3564 // result = this.request( concept, id || filter.filter, filter.criteria ); 3565 // 3566 // if( result && bothSides && (!filter || 3567 // !filter.criteria || 3568 // !filter.criteria.format) ) 3569 // { 3570 // var newResult = []; 3571 // 3572 // for( var i = 0; i < result.length; i++ ) 3573 // newResult[i] = $.extend( {}, result[i] ); 3574 // 3575 // this.put( concept, id, newResult, false ); 3576 // } 3577 // } 3578 // 3579 // if( /*result &&*/ encoder ) 3580 // result = this.encode( encoder, result, filter ); //TODO: retirar o filtro no método encode 3581 // 3582 // return( result ); 3583 // }, 3584 // 3585 // filter: function( base, filter, criteria ){ 3586 // 3587 // var filtered = []; 3588 // 3589 // for( var key in base ) 3590 // { 3591 // // if( !noGroup ) 3592 // // for( var i = 0, current = original; i < filter.length && ( current === original ); i++ ) 3593 // // current = this.compare( operator, current, this.compare( base[key], filter[i] ) ); 3594 // 3595 // if( this.storage.filter( base[key], filter ) ) 3596 // filtered[ filtered.length ] = key; 3597 // } 3598 // 3599 // return( filtered ); 3600 // }, 3601 // 3602 // compare: function( operator, base, test ){ 3603 // 3604 // switch( operator ) 3605 // { 3606 // case '*': return RegExp( ".*" + test + ".*" ).test( base ); 3607 // case '^': return RegExp( "^" + test + ".*" ).test( base ); 3608 // case '$': return RegExp( ".*" + test + "$" ).test( base ); 3609 // 3610 // case '&': return ( base && test ); 3611 // case '|': return ( base || test ); 3612 // 3613 // case '=': return ( base == test ); 3614 // case '<=': return ( base <= test ); 3615 // case '>=': return ( base >= test ); 3616 // case '>': return ( base < test ); 3617 // case '<': return ( base > test ); 3618 // } 3619 // 3620 // }, 3621 // 3622 // // clone: function( object ){ 3623 // // 3624 // // new { prototype: object }; 3625 // // 3626 // // }, 3627 // 3628 // check: function( namespace, keys ){ 3629 // 3630 // if( !namespace ) 3631 // return( false ); 3632 // 3633 // var result = this.storage.get( namespace ); 3634 // 3635 // if( !keys || !result ) 3636 // return( result || false ); 3637 // 3638 // if( notArray = $.type(keys) === "string" ) 3639 // keys = [ keys ]; 3640 // else if( $.type(keys) !== "array" ) 3641 // keys = this.filter( result, keys.filter, keys.criteria ); 3642 // 3643 // var res = []; 3644 // 3645 // for( var i = 0; i < keys.length; i++ ) 3646 // res[ res.length ] = result[keys[i]]; 3647 // 3648 // return( notArray ? res[0] || false : res.length ? res : false ); 3649 // }, 3650 // 3651 // storage: { 3652 // 3653 // cache: {}, 3654 // 3655 // set: function( key, value ){ 3656 // 3657 // this.cache[key] = value; 3658 // 3659 // }, 3660 // get: function( key ){ 3661 // 3662 // return DataLayer.copy( this.cache[key] ); 3663 // 3664 // }, 3665 // del: function( key ){ 3666 // 3667 // delete this.cache[key]; 3668 // 3669 // }, 3670 // 3671 // filter: function( base, filter ){ 3672 // 3673 // var bool, op = filter.shift(); 3674 // 3675 // switch( op ) 3676 // { 3677 // case 'IN': 3678 // for( var i = 0, f = []; i < filter[1].length || !(filter = f); i++ ) 3679 // f[i] = [ '=', filter[0], filter[1][i] ]; 3680 // case 'OR': 3681 // op = '|'; 3682 // bool = false; 3683 // break; 3684 // case 'AND': 3685 // op = '&'; 3686 // bool = true; 3687 // break; 3688 // default : return DataLayer.compare( op, base[ filter[0] ], filter[1] ); 3689 // } 3690 // 3691 // for( var strict = bool; 3692 // 3693 // filter.length && ( strict ? bool : !bool ); 3694 // 3695 // bool = DataLayer.compare( op, bool, this.filter( base, filter.shift() ) ) ); 3696 // 3697 // return( bool ); 3698 // } 3699 // }, 3700 // 3701 // flush: function(){ 3702 // 3703 // }, 3704 // 3705 // restore: function(){ 3706 // 3707 // }, 3708 // 3709 // store: function( namespace, key, data ){ 3710 // 3711 // if( !data ) 3712 // return this.storage.set( namespace, key ); 3713 // 3714 // var res = this.check( namespace ) || {}; 3715 // 3716 // res[key] = data; 3717 // 3718 // return this.storage.set( namespace, res ); 3719 // }, 3720 // 3721 // del: function( namespace, key ){ 3722 // 3723 // if( !key ) 3724 // return this.storage.del( namespace ); 3725 // 3726 // var res = this.check( namespace ) || {}; 3727 // 3728 // delete res[key]; 3729 // 3730 // return this.storage.set( namespace, res ); 3731 // 3732 // }, 3733 // 3734 // move: function( concept, oldId, newId ){ 3735 // 3736 // this.put( concept, newId, this.check( concept, oldId ), false ); 3737 // 3738 // this.remove( concept, oldId, false ); 3739 // }, 3740 // 3741 // 3742 // 3743 // 3744 // 3745 // request: function( concept, filter, criteria ){ 3746 // 3747 // var id = false, criteria = criteria || {}; 3748 // 3749 // if( $.type(filter) === "string" ) 3750 // { 3751 // id = filter; 3752 // filter = false; 3753 // } 3754 // 3755 // return this.dispatch( "request", { 3756 // 3757 // concept: concept || '', 3758 // id: id || '', 3759 // filter: filter || '', 3760 // criteria: criteria || '', 3761 // service: criteria.service || '', 3762 // properties: criteria.properties || '' 3763 // 3764 // } ); 3765 // }, 3766 // 3767 // 3768 // // sync: function( data, callback ){ 3769 // // 3770 // // if( !data || $.isEmptyObject( data ) ) 3771 // // return; 3772 // // 3773 // // this.send( "Sync", data, function( data, status, jqXHR ){ 3774 // // 3775 // // // switch( status ) 3776 // // // { 3777 // // // case "error": 3778 // // // case "parsererror": 3779 // // // return DataLayer.rollback( concept, URI ); 3780 // // // case "success": 3781 // // // return DataLayer.commit(); 3782 // // // case "timeout": 3783 // // // case "notmodified": 3784 // // // } 3785 // // 3786 // // if( callback ) 3787 // // { 3788 // // var result = callback( data, status, jqXHR ); 3789 // // 3790 // // if( result === false ) 3791 // // return; 3792 // // else if( typeof result != "undefined" ) 3793 // // data = result; 3794 // // } 3795 // // 3796 // // for( var URI in data ) 3797 // // { 3798 // // var parsed = DataLayer.parseURI( URI ), 3799 // // 3800 // // concept = parsed[1], /*URI = parsed[3],*/ 3801 // // 3802 // // links = DataLayer.links( concept ); 3803 // // 3804 // // for( var linkName in links ) 3805 // // { 3806 // // var subURI = data[URI][linkName]; 3807 // // 3808 // // if( subURI && data[subURI] ) 3809 // // { 3810 // // data[URI][linkName] = DataLayer.put( linkName, subURI, data[subURI], false ); 3811 // // 3812 // // delete( data[subURI] ); 3813 // // } 3814 // // } 3815 // // 3816 // // DataLayer.put( concept, URI, data[URI], false ); 3817 // // } 3818 // // }, true ); 3819 // // 3820 // // }, 3821 // 3822 // // report: function( concept, URI, data, sync ) 3823 // // { 3824 // // var current = this.dequeue( 'current', concept, URI ); 3825 // // 3826 // // if( !current ) 3827 // // this.enqueue( 'current', concept, URI, ( current = this.check( concept, URI ) || {} ) ); 3828 // // 3829 // // var diff = this.diff( current, data ); 3830 // // 3831 // // if( !diff ) 3832 // // this.dequeue( 'current', concept, URI, true ); 3833 // // else 3834 // // this.enqueue( 'diff', concept, URI, diff ); 3835 // // 3836 // // if( sync ) 3837 // // this.commit( concept, URI, function(){ 3838 // // 3839 // // DataLayer.set( concept, URI, data, false ); 3840 // // 3841 // // }); 3842 // // }, 3843 // 3844 // // enqueue: function( type, concept, URI, obj ){ 3845 // // 3846 // // //var newURI = this.URI( concept, URI ); 3847 // // 3848 // // if( !this.queue[type] ) 3849 // // this.queue[type] = {}; 3850 // // 3851 // // if( !this.queue['all'] ) 3852 // // this.queue['all'] = {}; 3853 // // 3854 // // if( !this.queue[type][concept] ) 3855 // // this.queue[type][concept] = {}; 3856 // // 3857 // // if( !this.queue['all'][type] ) 3858 // // this.queue['all'][type] = {}; 3859 // // 3860 // // if( !this.queue['all'][type][/*new*/URI] ) 3861 // // this.queue[type][concept][URI] = this.queue['all'][type][/*new*/URI] = obj; 3862 // // 3863 // // this.store( ':queue', this.queue ); 3864 // // }, 3865 // // 3866 // // dequeue: function( type, concept, URI, remove ){ 3867 // // 3868 // // ///////////////////////////// normalize //////////////////////////////// 3869 // // if( arguments.length < 4 && $.type(URI) === 'boolean' ) 3870 // // { 3871 // // remove = URI; 3872 // // URI = false; 3873 // // } 3874 // // if( arguments.length < 3 && $.type(concept) === 'boolean' ) 3875 // // { 3876 // // remove = concept; 3877 // // concept = false; 3878 // // } 3879 // // ////////////////////////////////////////////////////////////////////////// 3880 // // 3881 // // if( !this.queue[type] || !this.queue['all'] ) 3882 // // return( false ); 3883 // // 3884 // // if( !concept ) 3885 // // { 3886 // // var obj = this.queue['all'][type]; 3887 // // 3888 // // if( remove ) 3889 // // { 3890 // // delete this.queue['all'][type]; 3891 // // delete this.queue[type]; 3892 // // } 3893 // // 3894 // // this.store( ':queue', this.queue ); 3895 // // return( obj ); 3896 // // } 3897 // // 3898 // // if( !this.queue[type][concept] ) 3899 // // return( false ); 3900 // // 3901 // // if( !URI ) 3902 // // { 3903 // // var obj = this.queue[type][concept]; 3904 // // 3905 // // if( remove ) 3906 // // { 3907 // // var URIs = this.queue[type][concept]; 3908 // // 3909 // // for( var subURI in URIs ) 3910 // // delete this.queue['all'][type][subURI]; 3911 // // 3912 // // delete this.queue[type][concept]; 3913 // // } 3914 // // 3915 // // this.store( ':queue', this.queue ); 3916 // // return( obj ); 3917 // // } 3918 // // 3919 // // // var newURI = URI ? this.URI( concept, URI ) : concept; 3920 // // 3921 // // var obj = this.queue['all'][type][/*new*/URI]; 3922 // // 3923 // // if( remove ) 3924 // // { 3925 // // delete this.queue['all'][type][/*new*/URI]; 3926 // // delete this.queue[type][concept][URI]; 3927 // // } 3928 // // 3929 // // this.store( ':queue', this.queue ); 3930 // // return( obj ); 3931 // // }, 3932 // 3933 // //TODO: definir a 'usage' desta função e refatora-la 3934 // // set: function( concept, filter, data, oneSide ){ 3935 // // 3936 // // ///////////////////////////// normalize //////////////////////////////// 3937 // // if( arguments.length == 2 ) 3938 // // { 3939 // // data = filter; 3940 // // filter = false; 3941 // // } 3942 // // if( $.type(data) === "boolean" ) 3943 // // { 3944 // // oneSide = data; 3945 // // data = filter; 3946 // // filter = false; 3947 // // } 3948 // // 3949 // // if( !concept || !data ) 3950 // // return( false ); 3951 // // 3952 // // var decoder = "", URI = false, bothSides = (typeof oneSide === "undefined"); 3953 // // 3954 // // if( $.type(filter) === "string" ) 3955 // // { 3956 // // URI = filter; 3957 // // filter = false; 3958 // // } 3959 // // 3960 // // if( res = internalUrl.exec( concept ) ) 3961 // // { 3962 // // //TODO: verificar se a decodificaçao deve ser feita em cada item do array 3963 // // data = this.decode( concept, data ); 3964 // // concept = res[1]; 3965 // // decoder = res[2]; 3966 // // } 3967 // // /////////////////////////////////////////////////////////////////////////// 3968 // // 3969 // // if( bothSides || oneSide ) 3970 // // this.report( concept, URI, data, !bothSides ); 3971 // // 3972 // // if( bothSides || !oneSide ) 3973 // // { 3974 // // if( URI ) 3975 // // { 3976 // // var helper = {}; 3977 // // helper[URI] = data; 3978 // // data = helper; 3979 // // } 3980 // // 3981 // // for( var URI in data ) 3982 // // { 3983 // // var current = this.check( concept, URI ) || {}; 3984 // // 3985 // // data[URI] = this.merge( current, data[URI] ); 3986 // // 3987 // // this.store( concept, URI, data[URI] ); 3988 // // } 3989 // // 3990 // // } 3991 // // 3992 // // this.broadcast( concept, oneSide ? 'client' : 'server' ); 3993 // // 3994 // // return( true ); 3995 // // }, 3996 // // put: function( concept, URI, data, oneSide ){ 3997 // // 3998 // // ///////////////////////////// normalize //////////////////////////////// 3999 // // if( $.type(URI) !== "string" && arguments.length < 4 ) 4000 // // { 4001 // // oneSide = data; 4002 // // data = URI; 4003 // // URI = false; 4004 // // } 4005 // // //////////////////////////////////////////////////////////////////////// 4006 // // 4007 // // ////////////////////////////// linkage ///////////////////////////////// 4008 // // var result = false, links = this.links( concept ); 4009 // // 4010 // // for( var link in links ) 4011 // // { 4012 // // if( data[link] ) 4013 // // { 4014 // // if( $.isArray( data[link] ) ) 4015 // // { 4016 // // data[link] = this.put( links[link], data[link].URI, data[link], oneSide ); 4017 // // } 4018 // // else if( $.isObject( data[link] ) ) 4019 // // { 4020 // // $.each( data[link], function( i, el ){ 4021 // // 4022 // // data[link][i] = this.put( links[link], el.URI, el, oneSide ); 4023 // // 4024 // // }); 4025 // // } 4026 // // } 4027 // // } 4028 // // ////////////////////////////////////////////////////////////////////////// 4029 // // 4030 // // if( typeof data.URI === "undefined" ) 4031 // // { 4032 // // URI = this.add( concept, data, oneSide ); 4033 // // } 4034 // // else if( data.URI === false ) 4035 // // { 4036 // // status = this.remove( concept, URI, oneSide ); 4037 // // } 4038 // // else 4039 // // { 4040 // // status = this.set( concept, URI, data, oneSide ); 4041 // // } 4042 // // 4043 // // if( URI && data.URI && URI !== data.URI ) 4044 // // this.move( concept, URI, data.URI ); 4045 // // 4046 // // return( data.URI || URI ); 4047 // // 4048 // // }, 4049 // 4050 // // add: function( concept, data, oneSide ){ 4051 // // 4052 // // ///////////////////////////// normalize //////////////////////////////// 4053 // // if( !concept || !data ) 4054 // // return( false ); 4055 // // 4056 // // if( res = internalUrl.exec( concept ) ) 4057 // // { 4058 // // //TODO: verificar se a decodificaï¿Åï¿Åo deve ser feita em cada item do array 4059 // // data = this.decode( concept, data ); 4060 // // concept = res[1]; 4061 // // decoder = res[2]; 4062 // // } 4063 // // 4064 // // var bothSides = (typeof oneSide === "undefined"), uris = []; 4065 // // 4066 // // if( notArray = $.type(data) !== "array" ) 4067 // // data = [ data ]; 4068 // // ////////////////////////////////////////////////////////////////////////// 4069 // // 4070 // // for( var i = 0; i < data.length; i++ ) 4071 // // { 4072 // // var URI = uris[i] = this.generateURI( concept ); 4073 // // 4074 // // this.set( concept, URI, data[i], oneSide ); 4075 // // } 4076 // // 4077 // // return( notArray ? uris[0] : uris ); 4078 // // }, 4079 // // put: function( concept, data ){ 4080 // // 4081 // // var decoder = ""; 4082 // // 4083 // // if( res = internalUrl.exec( concept ) ) 4084 // // { 4085 // // data = this.decode( concept, data ); 4086 // // concept = res[1]; 4087 // // decoder = res[2]; 4088 // // } 4089 // // 4090 // // var New = [], Update = [], uris = []; 4091 // // 4092 // // if( notArray = $.type(data) !== "array" ) 4093 // // data = [ data ]; 4094 // // 4095 // // for( var i = 0; i < data.length; i++ ) 4096 // // { 4097 // // if( !data[i].URI ) 4098 // // { 4099 // // uris[ uris.length ] = data[i].URI = this.create( concept, data[i] ); 4100 // // New[ New.length ] = data[i]; 4101 // // continue; 4102 // // } 4103 // // 4104 // // for( var key in data[i] ) 4105 // // if( klass = this.isReference( concept, key, data[i][key] ) ) 4106 // // data[i][key] = this.put( klass + decoder, data[i][key] ); 4107 // // 4108 // // Update[ Update.length ] = this.update( concept, data[i].URI, data[i] ); 4109 // // } 4110 // // 4111 // // this.report( concept, { "created": New, "updated": Update }); 4112 // // 4113 // // return( notArray ? uris[0] : uris ); 4114 // // }, 4115 // // merge: function( concept, current, data ){ 4116 // // 4117 // // current = current || {}; 4118 // // 4119 // // for( var key in data ) 4120 // // current[key] = (klass = this.isReference( concept, key, data[key] )) ? 4121 // // this.merge( klass, current[key], data[key] ) : data[key]; 4122 // // 4123 // // return( current ); 4124 // // }, 4125 // // 4126 // // isReference: function( concept, key, value ){ 4127 // // 4128 // // return( ($.type(value) === "object" || 4129 // // $.type(value) === "array" )? this.links[concept][key] : false ); 4130 // // 4131 // // }, 4132 // // 4133 // // set: function( concept, data, URI, mergeable ){ 4134 // // 4135 // // if( URI ) 4136 // // { 4137 // // var res = this.get( concept, true ) || {}; 4138 // // 4139 // // if( mergeable ) 4140 // // data = this.merge( res[URI] || {}, data ); 4141 // // 4142 // // res[URI] = data; 4143 // // 4144 // // data = res; 4145 // // } 4146 // // 4147 // // return this.store( concept, data ); 4148 // // }, 4149 // // 4150 // // create: function( concept, data ){ 4151 // // 4152 // // if( notArray = ($.type(data) !== "array") ) 4153 // // data = [ data ]; 4154 // // 4155 // // var uris = []; 4156 // // 4157 // // for( var i = 0; i < data.length; i++ ) 4158 // // { 4159 // // uris[ uris.length ] = data[i].URI = "javascript://" + (this.counter + i); 4160 // // 4161 // // this.set( concept, data[i], data[i].URI ); 4162 // // } 4163 // // 4164 // // this.set( ":counter", (this.counter += data.length) ); 4165 // // 4166 // // return notArray ? uris[0] : uris; 4167 // // }, 4168 // // 4169 // // update: function( concept, URI, data ) 4170 // // { 4171 // // var target = this.check( concept, URI ) || {}; 4172 // // 4173 // // target = this.merge( concept, target, data ); 4174 // // 4175 // // if( target.URI !== URI ) 4176 // // this.remove( concept, URI ); 4177 // // 4178 // // this.set( concept, target, target.URI ); 4179 // // 4180 // // return( target ); 4181 // // }, 4182 // // 4183 // // remove: function( concept, URI ){ 4184 // // 4185 // // if( !URI ) 4186 // // return this.storage.del( concept ); 4187 // // 4188 // // var res = this.check( concept ); 4189 // // 4190 // // delete res[URI]; 4191 // // 4192 // // this.set( concept, res ); 4193 // // }, 4194 // // 4195 // // del: function( concept, URI ){ 4196 // // 4197 // // this.remove( concept, URI ); 4198 // // 4199 // // this.report( concept, { "deleted": { 'URI': URI } }); 4200 // // }, 4201 // // 4202 // // report: function( concept, changes ){ 4203 // // 4204 // // this.broadcast( concept, changes.created, changes.updated, changes.deleted ); 4205 // // 4206 // // if( changes.created ) 4207 // // this.sync( concept, changes.created, 'create' ); 4208 // // if( changes.updated ) 4209 // // this.sync( concept, changes.updated, 'update' ); 4210 // // if( changes.deleted ) 4211 // // this.sync( concept, changes.deleted, 'delete' ); 4212 // // 4213 // // }, 4214 // // 4215 // // 4216 // // sync: function( concept, data, type ){ 4217 // // 4218 // // if( $.type(data) !== "array" ) 4219 // // data = [ data ]; 4220 // // 4221 // // $.each( data, function( i, el ){ 4222 // // 4223 // // DataLayer.send( concept, el, type ); 4224 // // 4225 // // }); 4226 // // 4227 // // }, 4228 // // 4229 // // 4230 // // 4231 // // 4232 // // 4233 // // request: function( concept, URI, filter ){ 4234 // // 4235 // // // if( startsDoubleDot.test(concept) ) 4236 // // // return( false ); 4237 // // 4238 // // filter = filter || {}; 4239 // // 4240 // // if( URI ) 4241 // // filter.URI = URI; 4242 // // 4243 // // return this.send( concept, filter, "read", true ); 4244 // // 4245 // // }, 4246 // // 4247 // // send: function( concept, data, type, wait ){ 4248 // // 4249 // // switch( type ) 4250 // // { 4251 // // case "create": type = "POST"; break; 4252 // // case "update": type = "PUT"; break; 4253 // // case "delete": type = "DELETE"; break; 4254 // // case "read": type = "GET"; break; 4255 // // } 4256 // // 4257 // // var url = this.basePath + concept; 4258 // // 4259 // // var result = [], notArray = false; 4260 // // 4261 // // // alert( data.URI ); 4262 // // 4263 // // if( data.URI && data.URI.indexOf("javascript://") !== 0 ) 4264 // // url += "/" + data.URI; 4265 // // 4266 // // var callback = function( dt, textStatus, jqXHR ){ 4267 // // 4268 // // if( notArray = (!$.isArray( dt )) ) 4269 // // dt = [ dt ]; 4270 // // 4271 // // $.each( dt, function( i, el ){ 4272 // // 4273 // // if( !el || !el.URI ) 4274 // // return; 4275 // // 4276 // // if( data.URI ) 4277 // // el = DataLayer.update( concept, data.URI, el ); 4278 // // else 4279 // // DataLayer.set( concept, el, el.URI ); 4280 // // 4281 // // result[ result.length ] = el; 4282 // // DataLayer.broadcast( concept ); 4283 // // }); 4284 // // }; 4285 // // 4286 // // $.ajax({ 4287 // // 'async': ( !wait ), 4288 // // 'url': url, 4289 // // 'type': type, 4290 // // 'success': callback, 4291 // // 'dataType': 'json', 4292 // // 'data': data/*, 4293 // // 'processData': false*/ 4294 // // }); 4295 // // 4296 // // return( notArray ? result[0] || false : result ); 4297 // // }, 4298 // 4299 // 4300 // generateURI: function( concept ){ 4301 // 4302 // return this.URI( concept, this.generateId( concept ), "javascript" ); 4303 // 4304 // }, 4305 // 4306 // 4307 // broadcast: function( concept, status, diff ){ 4308 // 4309 // if( this.listeners[ concept ] ) 4310 // for( var i = 0; 4311 // i < this.listeners[ concept ].length; 4312 // this.listeners[ concept ][ i++ ]( status, diff ) ); 4313 // }, 4314 // 4315 // listen: function( concept, listener ){ 4316 // 4317 // this.register( "listeners", concept, listener ); 4318 // 4319 // }, 4320 // 4321 // codec: function( concept, namespace, codec ){ 4322 // 4323 // if( codec.encoder ) 4324 // this.encoder( concept, namespace, codec.encoder ); 4325 // if( codec.decoder ) 4326 // this.decoder( concept, namespace, codec.decoder ); 4327 // if( codec.criteria ) 4328 // this.register( "criterias", concept + ":" + namespace, codec.criteria ); 4329 // 4330 // }, 4331 // 4332 // encoder: function( concept, namespace, encoder ){ 4333 // 4334 // this.register( "encoders", concept + ":" + namespace, encoder ); 4335 // 4336 // }, 4337 // 4338 // encode: function( encoder, data, filter ){ 4339 // 4340 // if( this.encoders[ encoder ] ) 4341 // for( var i = 0; 4342 // i < this.encoders[ encoder ].length; 4343 // data = this.encoders[ encoder ][ i++ ]( data, filter ) ); 4344 // 4345 // return( data ); 4346 // }, 4347 // 4348 // decoder: function( concept, namespace, decoder ){ 4349 // 4350 // this.register( "decoders", concept + ":" + namespace, decoder ); 4351 // 4352 // }, 4353 // 4354 // decode: function( decoder, data ){ 4355 // 4356 // if( this.decoders[ decoder ] ) 4357 // for( var i = 0; 4358 // i < this.decoders[ decoder ].length; 4359 // data = this.decoders[ decoder ][ i++ ]( data ) ); 4360 // 4361 // return( data ); 4362 // }, 4363 // 4364 // criteria: function( codec, filter ){ 4365 // 4366 // if( this.criterias[ codec ] ) 4367 // for( var i = 0; 4368 // i < this.criterias[ codec ].length; 4369 // filter = this.criterias[ codec ][ i++ ]( filter ) ); 4370 // 4371 // return( filter ); 4372 // 4373 // }, 4374 // 4375 // register: function( kind, concept, deployable ){ 4376 // 4377 // if( arguments.length < 3 ) 4378 // { 4379 // deployable = concept; 4380 // concept = kind; 4381 // kind = 'global'; 4382 // } 4383 // 4384 // if( !this[ kind ][ concept ] ) 4385 // this[ kind ][ concept ] = []; 4386 // 4387 // this[ kind ][ concept ][ this[ kind ][ concept ].length ] = deployable; 4388 // 4389 // }, 4390 // 4391 // start: function(){ 4392 // 4393 // var timer = function(){ 4394 // 4395 // setTimeout( timer, 1 ); 4396 // 4397 // var now = parseInt( $.now() / 1000 ); 4398 // 4399 // var tasks = DataLayer.tasks[ now ]; 4400 // 4401 // if( !tasks ) return; 4402 // 4403 // for( var i = 0; i < tasks.length; i++ ) 4404 // { 4405 // var result = tasks[i].task( now ); 4406 // 4407 // if( tasks[i].factor ) 4408 // DataLayer.schedule( tasks[i].task, tasks[i].factor ); 4409 // } 4410 // 4411 // delete DataLayer.tasks[ now ]; 4412 // }; 4413 // 4414 // setTimeout( timer, 1 ); 4415 // }, 4416 // 4417 // task: function( timestamp, task, factor ) 4418 // { 4419 // if( !this.tasks[ timestamp ] ) 4420 // this.tasks[ timestamp ] = []; 4421 // 4422 // this.tasks[ timestamp ][ this.tasks[ timestamp ].length ] = { task: task, factor: factor || false }; 4423 // }, 4424 // 4425 // schedule: function( task, time ){ 4426 // 4427 // time = time || 1; 4428 // 4429 // var index = parseInt( $.now() / 1000 ) + time; 4430 // 4431 // this.task( index, task, time ); 4432 // }, 4433 // 4434 // poll: function( concept, time ){ 4435 // 4436 // this.schedule( function( now ){ 4437 // 4438 // DataLayer.commit( concept ); 4439 // 4440 // }, time || 5 ); 4441 // }, 4442 // 4443 // init: function(){ 4444 // 4445 // this.counter = parseInt( this.get( ":counter", false ) ) || 0; 4446 // 4447 // if( !this.dispatchPath ) 4448 // this.dispatchPath = "../../"; 4449 // 4450 // if( !this.templatePath ) 4451 // this.templatePath = ""; 4452 // 4453 // if( !this.basePath ) 4454 // this.basePath = this.dispatchPath + "REST.php?q="; 4455 // 4456 // this.schedule( function( now ){ 4457 // 4458 // DataLayer.flush(); 4459 // 4460 // }); 4461 // 4462 // this.start(); 4463 // } 4464 // } 4465 // 4466 // // the re-usable constructor function used by clone(). 4467 // function Clone() {} 4468 // 4469 // //Recursion Helper 4470 // function RecursionHelper(){ this.clear(); }; 4471 // 4472 // RecursionHelper.prototype = { 4473 // 4474 // constructor: RecursionHelper, 4475 // 4476 // // copiedObjects keeps track of objects already copied by this 4477 // // deepCopy operation, so we can correctly handle cyclic references. 4478 // copiedObjects: [], 4479 // 4480 // depth: 0, 4481 // 4482 // maxDepth: 256, 4483 // 4484 // //reset the recursion helper cache 4485 // clear: function(){ 4486 // this.copiedObjects = []; 4487 // this.depth = 0; 4488 // }, 4489 // 4490 // // add an object to the cache. No attempt is made to filter duplicates; 4491 // // we always check getCachedResult() before calling it. 4492 // cacheResult: function(source, result) { 4493 // this.copiedObjects.push([source, result]); 4494 // }, 4495 // 4496 // // Returns the cached copy of a given object, or undefined if it's an 4497 // // object we haven't seen before. 4498 // getCachedResult: function(source) { 4499 // 4500 // for ( var i=0; i<this.copiedObjects.length; i++ ) { 4501 // if ( this.copiedObjects[i][0] === source ) { 4502 // return this.copiedObjects[i][1]; 4503 // } 4504 // } 4505 // 4506 // return undefined; 4507 // } 4508 // }; 4509 // 4510 // // Generic Object copier 4511 // // the ultimate fallback DeepCopier, which tries to handle the generic case. This 4512 // // should work for base Objects and many user-defined classes. 4513 // DataLayer.registerComparator({ 4514 // can: function(source) { return true; }, 4515 // 4516 // create: function(source) { 4517 // if ( source instanceof source.constructor ) { 4518 // return DataLayer.clone(source.constructor.prototype); 4519 // } else { 4520 // return {}; 4521 // } 4522 // }, 4523 // 4524 // populate: function(deepCopy, source, result) { 4525 // for ( var key in source ) { 4526 // if ( source.hasOwnProperty(key) ) { 4527 // result[key] = deepCopy(source[key], result[key]); 4528 // } 4529 // } 4530 // return result; 4531 // } 4532 // }); 4533 // 4534 // // Array copier 4535 // DataLayer.registerComparator({ 4536 // can: function(source) { 4537 // return ( source instanceof Array ); 4538 // }, 4539 // 4540 // create: function(source) { 4541 // return new source.constructor(); 4542 // }, 4543 // 4544 // populate: function(deepCopy, source, result) { 4545 // for ( var i=0; i<source.length; i++) { 4546 // result.push( deepCopy(source[i], result[i]) ); 4547 // } 4548 // result = DataLayer.unique( result ) 4549 // return result; 4550 // } 4551 // }); 4552 // 4553 // // Date copier 4554 // DataLayer.registerComparator({ 4555 // can: function(source) { 4556 // return ( source instanceof Date ); 4557 // }, 4558 // 4559 // create: function(source) { 4560 // return new Date(source); 4561 // } 4562 // }); 4563 // 4564 // // HTML DOM Node copier 4565 // DataLayer.registerComparator({ 4566 // 4567 // // function to detect Nodes. In particular, we're looking 4568 // // for the cloneNode method. The global document is also defined to 4569 // // be a Node, but is a special case in many ways. 4570 // can: function(source) { 4571 // 4572 // if ( window.Node ) { 4573 // return source instanceof Node; 4574 // } else { 4575 // // the document is a special Node and doesn't have many of 4576 // // the common properties so we use an identity check instead. 4577 // if ( source === document ) return true; 4578 // return ( 4579 // typeof source.nodeType === 'number' && 4580 // source.attributes && 4581 // source.childNodes && 4582 // source.cloneNode 4583 // ); 4584 // } 4585 // }, 4586 // 4587 // create: function(source) { 4588 // // there can only be one (document). 4589 // if ( source === document ) return document; 4590 // 4591 // // start with a shallow copy. We'll handle the deep copy of 4592 // // its children ourselves. 4593 // return source.cloneNode(false); 4594 // }, 4595 // 4596 // diff: function(base, source){ 4597 // 4598 // }, 4599 // 4600 // populate: function(deepCopy, source, result) { 4601 // // we're not copying the global document, so don't have to populate it either. 4602 // if ( source === document ) return document; 4603 // 4604 // // if this Node has children, deep copy them one-by-one. 4605 // if ( source.childNodes && source.childNodes.length ) { 4606 // for ( var i=0; i<source.childNodes.length; i++ ) { 4607 // var childCopy = deepCopy(source.childNodes[i], result.childNodes[i] || false ); 4608 // result.appendChild(childCopy); 4609 // } 4610 // } 4611 // return result; 4612 // } 4613 // }); 4614 // 4615 // DataLayer.init(); 4616 // 4617 // // setTimeout(function(){ 4618 // // 4619 // // 4620 // // 4621 // // }, 1000 ); 4622 // 4623 // // var DataLayer = { 4624 // // 4625 // // get: function( concept, filter ){ 4626 // // 4627 // // var data = this.storage.get( concept ); 4628 // // 4629 // // if( !filter ) 4630 // // return( data ); 4631 // // 4632 // // return this.filter( data, filter ); 4633 // // }, 4634 // // 4635 // // filter:function( data, filter ){ 4636 // // 4637 // // if( filter.charAt ) 4638 // // filter = { URI: filter }; 4639 // // 4640 // // var filtered = []; 4641 // // 4642 // // $.each(data, function(i, obj){ 4643 // // 4644 // // for( var attr in filter ) 4645 // // if( filter[attr] !== obj[attr] ) 4646 // // return( true ); 4647 // // 4648 // // filtered[i] = obj; 4649 // // }); 4650 // // 4651 // // return( filtered ); 4652 // // }, 4653 // // 4654 // // find: function( concept, filter, callback ){ 4655 // // 4656 // // var data = this.get( concept, filter ); 4657 // // 4658 // // if( data ) 4659 // // return callback( data ); 4660 // // 4661 // // //TODO: register callback like a weak listener 4662 // // 4663 // // // $.ajax({ 4664 // // // type: 'GET', 4665 // // // data: $.param( filter ), 4666 // // // success: callback, 4667 // // // url: BASE_PATH + filter.URI || concept 4668 // // // }); 4669 // // this.report( concept, filter ); 4670 // // }, 4671 // // 4672 // // put: function( concept, data, filter ){ 4673 // // 4674 // // var beforeDiff = this.store( concept, $.extend({},data) ); 4675 // // 4676 // // this.report( concept, data, filter, beforeDiff ); 4677 // // }, 4678 // // 4679 // // 4680 // // /*var data = { 4681 // // startTime: $.now(), 4682 // // endTime: $.now() + 1800000, 4683 // // summary: "meu querido evento", 4684 // // description: "desc do evento", 4685 // // location: "prognus software livre", 4686 // // class: 1, 4687 // // calendar: 1, 4688 // // category: 1, 4689 // // participants: [ { 4690 // // user: { isExternal: true, mail: "user7@prognus.org", name: "user7" } 4691 // // },{ 4692 // // user: "1003" 4693 // // } ] 4694 // // 4695 // // };*/ 4696 // // 4697 // // 4698 // // merge:function( data, target ){ 4699 // // 4700 // // var diff = { New: {}, Update:{}, Delete: {} }; 4701 // // 4702 // // for( var key in data ) 4703 // // { 4704 // // if( !target[ key ] ) 4705 // // diff.New[ key ] = target[ key ] = data[ key ]; 4706 // // 4707 // // 4708 // // 4709 // // } 4710 // // 4711 // // } 4712 // // 4713 // // store: function( concept, data, filter ){ 4714 // // 4715 // // if( !data.spline ) 4716 // // data = [ data ]; 4717 // // 4718 // // var target = this.storage.get( concept ); 4719 // // 4720 // // var diff = { New: {}, Update:{}, Delete: {} }; 4721 // // 4722 // // for( var i = 0; i < data.length; i++ ) 4723 // // { 4724 // // if( data[i].URI && target[ data[i].URI ] ) 4725 // // { 4726 // // diff.Update[ data[i].URI ] = this.merge( target[ data[i].URI ], data[i] ); 4727 // // } 4728 // // else 4729 // // { 4730 // // diff.New[] = data[i]; 4731 // // } 4732 // // } 4733 // // 4734 // // 4735 // // 4736 // // this.broadcast( concept, data ); 4737 // // 4738 // // if( filter ) 4739 // // target = this.filter( target, filter ); 4740 // // 4741 // // if( target ) 4742 // // data = $.extend( target, data ); 4743 // // 4744 // // this.storage.set( concept, data ); 4745 // // 4746 // // // return; 4747 // // }, 4748 // // 4749 // // set: function( concept, data, filter ){ 4750 // // 4751 // // 4752 // // 4753 // // }, 4754 // // 4755 // // post: function( concept, data, filter, isNew ){ 4756 // // 4757 // // var callback = function( ){ DataLayer.store( concept, data, filter ) }; 4758 // // 4759 // // //TODO: register callback like a weak listener 4760 // // 4761 // // this.report( concept, data, filter, isNew ); 4762 // // }, 4763 // // 4764 // // report: function( concept, filter, postData, isNew ){ 4765 // // 4766 // // $.ajax({ 4767 // // type: postData ? isNew ? 'POST' : 'PUT' : 'GET', 4768 // // data: postData || $.param( filter ), 4769 // // success: function( data ){ DataLayer.broadcast( concept ) }, 4770 // // url: BASE_PATH + filter.URI || concept 4771 // // }); 4772 // // }, 4773 // // 4774 // // del:function( concept, filter ){ 4775 // // 4776 // // 4777 // // 4778 // // } 4779 // // 4780 // // broadcast: function( concept, data ){ 4781 // // 4782 // // 4783 // // 4784 // // }, 4785 // // 4786 // // pool: function(){ 4787 // // 4788 // // }, 4789 // // 4790 // // refresh: function(){ 4791 // // 4792 // // } 4793 // // }; 4794 // 4795 // // 4796 // // DataLayer = { 4797 // // 4798 // // get: function( concept, filter ){ 4799 // // 4800 // // var data = this.storage.get( concept ); 4801 // // 4802 // // if( !filter ) 4803 // // return( data ); 4804 // // 4805 // // if( filter.charAt ) 4806 // // filter = { URI: filter }; 4807 // // 4808 // // var filtered = []; 4809 // // 4810 // // $.each(data, function(i, obj){ 4811 // // 4812 // // for( var attr in filter ) 4813 // // if( filter[attr] !== obj[attr] ) 4814 // // return( true ); 4815 // // 4816 // // filtered[i] = obj; 4817 // // }); 4818 // // 4819 // // return( filtered ); 4820 // // }, 4821 // // 4822 // // find: function( concept, filter, callback ){ 4823 // // 4824 // // var data = this.get( concept, filter ); 4825 // // 4826 // // if( data ) 4827 // // return callback( data ); 4828 // // 4829 // // $.ajax({ 4830 // // type: 'GET', 4831 // // data: $.param( filter ), 4832 // // success: callback, 4833 // // url: filter.URI || concept 4834 // // }); 4835 // // }, 4836 // // 4837 // // put: function( concept, data, filter ){ 4838 // // 4839 // // var target = this.get( concept, filter ); 4840 // // 4841 // // if( target ) 4842 // // data = $.extend( target, data ); 4843 // // 4844 // // this.storage.set( concept, data ); 4845 // // 4846 // // //diff 4847 // // }, 4848 // // 4849 // // post: function( concept, data, filter ){ 4850 // // 4851 // // 4852 // // 4853 // // }, 4854 // // 4855 // // pool: function(){ 4856 // // 4857 // // }, 4858 // // 4859 // // queue: function(){ 4860 // // 4861 // // }, 4862 // // 4863 // // dequeue: function(){ 4864 // // 4865 // // }, 4866 // // 4867 // // refresh: function(){ 4868 // // 4869 // // } 4870 // // } 4871 // 4872 // // var DataLayer = { 4873 // 4874 // // cache: {}, 4875 // 4876 // // get: function( concept, location ){ 4877 // 4878 // /* if( location ) 4879 // {*/ 4880 // // var schema = $.data( this.cache, concept + ':schema' ); 4881 // // var uri = []; 4882 // // 4883 // // $.each( schema, function( i, addrs ){ 4884 // // uri[ uri.length ] = location[addrs]; 4885 // // }); 4886 // 4887 // /*var filter = [], result = false; 4888 // 4889 // while( !(result = $.data( this.cache, uri.join( '.' ) )) || !(uri = uri.join('.')) ) 4890 // filter[ filter.length ] = uri.pop(); 4891 // 4892 // if( !filter.length ) 4893 // { 4894 // var indexes = $.data( this.cache, uri + ':indexes' ); 4895 // 4896 // if( indexes ) 4897 // Array.prototype.concat.apply( result, indexes ); 4898 // 4899 // return( result ); 4900 // } 4901 // 4902 // for( var i = 0; i < result.length; i++ ) 4903 // { 4904 // 4905 // } 4906 // 4907 // if( result.length ) 4908 // return( result ); 4909 // }*/ 4910 // 4911 // // var data = $.data( this.cache, concept ); 4912 // 4913 // // if( !data ) 4914 // // $.ajax( ); 4915 // 4916 // // return( data ); 4917 // // }, 4918 // 4919 // // data: function(){ 4920 // // 4921 // // 4922 // // 4923 // // } 4924 // // 4925 // // search: function( concept, filter ){ 4926 // // 4927 // // var schema = $.data( this.cache, concept + ':schema' ); 4928 // // var uri = []; 4929 // // 4930 // // $.each( schema, function( i, addrs ){ 4931 // // uri[ uri.length ] = location[addrs]; 4932 // // }); 4933 // // } 4934 // // put: function( concept, data, location ){ 4935 // 4936 // // if( location ) 4937 // // { 4938 // // var schema = $.data( this.cache, concept + ':schema'); 4939 // // var uri = []; 4940 // 4941 // // $.each( schema, function( i, addrs ){ 4942 // // uri[ uri.length ] = location[addrs]; 4943 // // }); 4944 // 4945 // // var result = false, filter = []; 4946 // 4947 // // while( !(result = $.data( this.cache, uri.join('.')) ) 4948 // // filter[ filter.length ] = uri.pop(); 4949 // 4950 // // $.data( this.cache, ' 4951 // 4952 // // } 4953 // 4954 // // var model = this.storage.get( concept ); 4955 // // 4956 // // $.each( model, function( i, o ){ 4957 // // $.each( location, function( ii, attr ){ 4958 // // if( o[ii] === attr ) 4959 // // return( false ); 4960 // // }); 4961 // // }); 4962 // 4963 // // return $.data( this.cache, concept, data ); 4964 // 4965 // // }, 4966 // // del: function( concept, location ){ 4967 // // 4968 // // if( location ) 4969 // // { 4970 // // var schema = $.data( this.cache, 'concepts', concept ); 4971 // // var uri = []; 4972 // // 4973 // // $.each( schema, function( i, addrs ){ 4974 // // uri[ uri.length ] = location[addrs]; 4975 // // }); 4976 // // 4977 // // concept = uri.join( '.' ); 4978 // 4979 // // var model = this.storage.get( concept ); 4980 // // 4981 // // $.each( model, function( i, o ){ 4982 // // $.each( location, function( ii, attr ){ 4983 // // if( o[ii] === attr ) 4984 // // return( false ); 4985 // // }); 4986 // // }); 4987 // // } 4988 // // 4989 // // 4990 // // $.removeData( this.cache, concept ); 4991 // // } 4992 // // } -
trunk/prototype/config/alarm.ini
r5437 r5514 2 2 PostgreSQL.concept = calendar_alarm 3 3 4 [ links]5 participant = participant 4 [model.depends] 5 participant = participant.alarm 6 6 7 7 [before.find] -
trunk/prototype/config/attachment.ini
r5399 r5514 1 1 service = PostgreSQL 2 PostgreSQL.concept = attachment 3 4 [model.hasOne] 5 schedulable = schedulable.attachments 2 6 3 7 [before.create] 4 beginWork = services/PostgreSQL.php5 8 encodeCreateAttachment = modules/calendar/interceptors/DBMapping.php 6 9 10 [after.delete] 11 deleteAttachmentDependences = modules/calendar/interceptors/DBMapping.php 7 12 8 [after.create] 9 endWork = services/PostgreSQL.php 13 [PostgreSQL.mapping] 14 id = "id" 15 source = "source" 16 type = "type" 17 name = "name" 18 size = "size" 19 -
trunk/prototype/config/calendar.ini
r5437 r5514 2 2 PostgreSQL.concept = calendar 3 3 4 [ links]5 signatures = calendarSignature 4 [model.hasMany] 5 signatures = calendarSignature.calendar 6 6 7 7 [before.create] -
trunk/prototype/config/calendarSignature.ini
r5437 r5514 2 2 PostgreSQL.concept = calendar_signature 3 3 4 [links] 5 calendar = calendar 6 calendarSignatureAlarms = calendarSignatureAlarm 4 [model.hasMany] 5 calendarSignatureAlarms = calendarSignatureAlarm.calendarSignature 6 [model.depends] 7 calendar = calendar.signatures 7 8 8 9 [before.delete] -
trunk/prototype/config/calendarSignatureAlarm.ini
r5437 r5514 2 2 PostgreSQL.concept = calendar_signature_alarm 3 3 4 [ links]5 calendarSignature = calendarSignature 4 [model.depends] 5 calendarSignature = calendarSignature.calendarSignatureAlarms 6 6 7 7 [after.find] -
trunk/prototype/config/participant.ini
r5437 r5514 2 2 PostgreSQL.concept = calendar_participant 3 3 4 [links] 5 user = user 6 schedulable = schedulable 7 alarms = alarm 4 [model.hasOne] 5 delegatedFrom = participant.delegateTo 6 delegateTo = participant.delegatedFrom 7 8 [model.hasMany] 9 alarms = alarm.participant 10 11 [model.depends] 12 user = user.participants 13 schedulable = schedulable.participants 8 14 9 15 [after.commit] … … 12 18 [PostgreSQL.mapping] 13 19 id = id 14 delegated To = delegated_to20 delegatedFrom = delegated_from 15 21 isOrganizer = is_organizer 16 22 isExternal = is_external … … 18 24 schedulable = object_id 19 25 user = user_info_id 26 acl = acl 27 receiveNotification = receive_notification -
trunk/prototype/config/repeat.ini
r5437 r5514 1 1 service = PostgreSQL 2 2 3 [ links]4 schedulable = schedulable 3 [model.depends] 4 schedulable = schedulable.repeat 5 5 -
trunk/prototype/config/schedulable.ini
r5437 r5514 2 2 PostgreSQL.concept = calendar_object 3 3 4 [links] 5 participants = participant 6 repeat = repeat 4 [model.hasMany] 5 participants = participant.schedulable 6 attachments = schedulableToAttachment.schedulable 7 8 [model.hasOne] 9 repeat = repeat.schedulable 7 10 8 11 [before.create] -
trunk/prototype/config/user.ini
r5437 r5514 9 9 PostgreSQL.concept = calendar_ex_participant 10 10 11 [ links]12 participants = participant 11 [model.hasMany] 12 participants = participant.user 13 13 14 14 [PostgreSQL.before.create] -
trunk/prototype/converter.php
r5415 r5514 3 3 require_once 'api/controller.php'; 4 4 5 $method = $_REQUEST['analize'] ? 'analize' : 'parse';5 $method = isset($_REQUEST['analize']) && $_REQUEST['analize'] ? 'analize' : 'parse'; 6 6 7 7 $args = Controller::call( $method, … … 9 9 array( 'service' => $_REQUEST['type'] ), 10 10 11 isset( $_FILES[' data'] ) ? file_get_contents( $_FILES['data']['tmp_name'] ) : $_REQUEST['data'],11 isset( $_FILES['files'] ) ? file_get_contents( $_FILES['files']['tmp_name'][0], $_FILES['files']['size'][0] ) : $_REQUEST['data'], 12 12 13 13 $_REQUEST['params'] ); 14 14 15 if( !$_REQUEST['readable'])15 if( !$_REQUEST['readable']) 16 16 require_once 'Sync.php'; 17 17 else -
trunk/prototype/links.php
r5399 r5514 15 15 { 16 16 $concepts = array(); 17 $nestedLinks = array(); 17 18 18 19 foreach( $link as $linkName => $linkTarget ) 19 if( Controller::isConcept( $linkName ) ) 20 { 21 if( Controller::isConcept( $concept, $linkName ) ) 20 22 $concepts[ $linkName ] = true; 21 23 22 $return[ $target ] = array( 'concepts' => $concepts, 'links' => $link ); 24 $nestedLinks[ $linkName ] = Controller::links( $concept, $linkName ); 25 } 26 27 $return[ $target ] = array( 'concepts' => $concepts, 'links' => $link, 'nestedLinks' => $nestedLinks ); 23 28 } 24 29 -
trunk/prototype/modules/calendar/constants.php
r5415 r5514 5 5 define('STATUS_CONFIRMED', 1); 6 6 define('STATUS_ACCEPTED', 1); 7 define('STATUS_TEN ATIVE', 2);7 define('STATUS_TENTATIVE', 2); 8 8 define('STATUS_DECLINED', 3); 9 9 define('STATUS_CANCELLED', 3); … … 29 29 define('ICAL_ACTION_NONE', 4); 30 30 define('ICAL_ACTION_REPLY', 5); 31 define('ICAL_ACTION_SUGGESTION', 6); 31 32 32 33 ?> -
trunk/prototype/modules/calendar/css/layout.css
r5417 r5514 211 211 } 212 212 213 .new-event-win fieldset.block-add-attendee-permissions { 214 width: 220px; 215 float:left; 216 margin: 105px 0 0 10px; 217 } 213 .new-event-win ul.attendee-permissions-list, li.attendee-permissions-list{text-align: left;} 214 215 li.attendee-permissions-list input{width: 20px !important; margin: 3px 0 0 0; !important} 216 217 p.request-update{display: inline; position: relative; top: 2px;} 218 219 220 p.request-update label{width: 150px !important;} 218 221 219 222 .new-event-win .menu-addevent { … … 221 224 } 222 225 223 fieldset.block-add-attendee .add-attendee-search { max-width: 2 00px; margin: 5px;}224 fieldset.block-add-attendee .add-attendee-search input { max-width: 170px;}226 fieldset.block-add-attendee .add-attendee-search { max-width: 250px; margin: 5px;} 227 fieldset.block-add-attendee .add-attendee-search input { max-width: 215px; width: 215px;} 225 228 fieldset.block-add-attendee .search-result-list { width: 255px; max-height: 215px; overflow: auto;} 226 229 fieldset.block-add-attendee .search-result-list .ui-widget-content { border: none;} … … 256 259 .attendees-list .me select.status { margin:10px 5px 5px 5px; } 257 260 .attendees-list .me .add-attendee-search { max-width: 155px; width:155px; display: inline; padding: 0; margin: 10px 0 5px 0;} 261 262 .attendees-list .me .add-attendee-options { max-height: 16px; height:16px; max-width: 50px; width:50px; display: inline; padding: 0; margin: 0 0 5px 0;} 263 .attendees-list .me .add-attendee-options-read { max-height: 16px; height:16px; max-width: 16px; width:16px; display: inline; padding: 0; margin: 0 0 5px 0;} 264 265 .attendees-list .me .add-attendee-options-button {position: absolute; top: 171px;} 266 .attendees-list .hover-attendee { background-color: #DFEFFC;} 267 /* 268 .attendees-list .attendee-options-button-edit { position: absolute; top:0; right:25px;} 269 .attendees-list .attendee-options-button-key { position: absolute; top:0; right:45px;} 270 .attendees-list .attendee-options-button-delegate { position: absolute; top:0; right:65px;} 271 */ 272 273 .attendee-options{ position: absolute; top: 0; left: 300px; background-color: white; z-index: 100; width: 90px; background-color: #FFF; padding: 0 5px 0 3px; text-align: right;} 274 .attendees-list .not-attendee { height:16px; } 275 276 .list-delegates{margin: 0 0 0 25px;} 277 278 .status-delegate{position: absolute; left:3px;} 279 258 280 .attendees-list .me .add-attendee-search input { max-width: 125px; } 259 .attendees-list li.organizer {margin-bottom: 3px;}281 .attendees-list li.organizer, .attendees-list li.me-delegated {margin-bottom: 3px;} 260 282 .attendees-list .organizer .button.swap { 261 283 float: right; 262 284 margin-top: -1.5em; 263 285 } 286 287 .name-status-delegated{text-decoration: line-through; padding: 0 0 0 18px;} 288 .name-status-delegated-delegated{text-decoration: line-through; padding: 0 0 0 12px;} 289 .name-status-delegated-none{ padding: 0 0 0 12;} 290 291 .name-status{padding: 0 0 0 18px;} 292 293 .name-special{padding: 0 0 0 33px;} 294 .name-special-delegated{text-decoration: line-through; padding: 0 0 0 33px;} 295 296 .open-delegate{position: absolute; left: 20px; display: block; cursor: hand;} 297 .space-status{position: absolute; left: 20px; display: block;} 298 .space-special{position: absolute; left: 35px; display: block;} 299 .space-special-delegated{position: absolute; left: 20px; display: block;} 300 301 .attendee-permissions-change{background-image: url(../../../plugins/jquery/images/ui-icons_f9bd01_256x240.png) !important;} 302 .attendee-permissions-change-button{border: 1px solid #79B7E7 !important; background: #F5F8F9 !important; font-weight: bold !important; color: #E17009 !important;} 303 304 .attendee-permissions-conflict{opacity: 0.5} 264 305 265 306 dd.attendee-list ul.attendee-list li { … … 275 316 dd.attendee-list ul.attendee-list li label.name, 276 317 dd.attendee-list ul.attendee-list li label.mail { 277 width: 6000px;278 min-width: 6000px;318 width: 99999px; 319 min-width: 99999px; 279 320 vertical-align: middle; 280 321 } 281 322 dd.attendee-list ul.attendee-list li label[title=''] { display:none } 323 /* 282 324 dd.attendee-list ul.attendee-list li .button.close { 283 325 position: absolute; 284 right: 0;326 right: 5px; 285 327 top: 0; 286 328 } 287 329 */ 288 330 /* 289 331 .attendees-list li .ui-icon-float-right { … … 482 524 } 483 525 526 .button.add.button-add-attachment{margin: -9px 0 0 8px;} 527 .button.upload{margin-bottom: 4px;} 528 div.fileupload-buttonbar{padding: 0.2em 0.5em } 529 .archive-error{color: #F00;} 530 531 .progress.in-progress{width: 100px; height: 12px;} 532 533 534 .lbl-archive-nome, .lbl-archive-size{font-weight: bold !important;} 535 .lbl-archive-nome{width:40px !important;} 536 .row.fileupload-buttonbar{margin-top: -14px; padding: 0.2em 0.7em;} 537 538 .archive-nome{width: 73px;} 539 .archive-nome label{display: block; position: absolute; left: 136px; top: 194px;} 540 .archive-size{min-width:100px; max-width:100px;} 541 542 484 543 .input-group.date-info input { 485 544 width: 100px; -
trunk/prototype/modules/calendar/css/style.css
r5511 r5514 90 90 91 91 .ui-dialog .ui-dialog-content { padding: 0; } 92 .new-event-win form.form-addevent { padding: 10px; } 92 .new-event-win div.div-addevent { padding: 0; width: 700px; border: 0;} 93 .new-event-win form.form-addevent { padding: 9px; } 93 94 94 95 .expresso-calendar-container input[type="text"] { height: 18px; } -
trunk/prototype/modules/calendar/export.php
r5399 r5514 31 31 $eventsIds[] = $eventLink['schedulable']; 32 32 33 $events = Controller::find(array('concept' => 'schedulable') , false , array('filter' => array('IN','id',$eventsIds) , 'deepness' => '2' )); 33 $events = Controller::find(array('concept' => 'schedulable') , false , array('filter' => array('IN','id',$eventsIds) , 'deepness' => '2' )); 34 34 $ics = Controller::format( array( 'service' => 'iCal' ) , $events , array('defaultTZI' => $calendar['timezone']) ); 35 35 … … 45 45 { 46 46 $event = Controller::read(array('concept' => 'schedulable' , 'id' => $params['event'])); 47 $attachmentRelation = Controller::find( array( 'concept' => 'schedulableToAttachment' ) , false ,array( 'filter' => array('=', 'schedulable' , $event['id']) )); 48 if(is_array($attachmentRelation)){ 49 $attachments = array(); 50 foreach($attachmentRelation as $key => $value) 51 if(isset($value['attachment']) || !!$value['attachment']) 52 $attachments[$key] = $value['attachment']; 53 //Pega os anexos sem source 54 $event['attachments'] = Controller::find( array( 'concept' => 'attachment' ) , false ,array( 'filter' => array('IN', 'id' , $attachments) )); 55 } 56 47 57 $ics = Controller::format( array( 'service' => 'iCal' ) , array($event) , array('defaultTZI' => $event['timezone']) ); 48 58 -
trunk/prototype/modules/calendar/interceptors/DBMapping.php
r5462 r5514 40 40 } 41 41 42 public function encodeCreateSuggestion( &$uri , &$params , &$criteria , $original ){ 43 $params['dtstamp'] = (isset($params['dtstamp'])) ? $params['dtstamp'] :time().'000'; 44 } 45 42 46 public function encodeUpdateAlarm( &$uri , &$params , &$criteria , $original ){ 43 47 if(isset($params['type'])) … … 46 50 47 51 public function encodeCreateAttachment( &$uri , &$params , &$criteria , $original ){ 48 $params['source'] = base64_encode( $params['source'] ); 52 53 if(!isset($params['source'])) return false; 54 55 if(isset($_FILES[$params['source']])) 56 if(isset($params['id'])) 57 $params = array_merge($_FILES[$params['source']], array('id' => $params['id'])); 58 else 59 $params = $_FILES[$params['source']]; 60 61 //$params['source'] = base64_encode( $params['source'] ); 62 49 63 } 64 50 65 /////////////////////////////////////////////////////////////////////////////////////////////////////////////// 51 66 … … 145 160 public function createCalendarToSchedulable( &$uri , &$result , &$criteria , $original ){ 146 161 147 Controller::create(array('concept' => 'calendarToSchedulable'), array('calendar' => $original['properties']['calendar'], 'schedulable' => $result['id'] )); 148 149 } 162 Controller::create(array('concept' => 'calendarToSchedulable'), array('calendar' => $original['properties']['calendar'], 'schedulable' => $result['id'] )); 163 164 } 165 166 public function createCreateSchedulableToAttachment( &$uri , &$params , &$criteria , $original ){ 167 if(array_key_exists('attachments', $original['properties'])) 168 foreach($original['properties']['attachments'] as $key => $value){ 169 if(isset($params['id'])) 170 Controller::create(array('concept' => 'schedulableToAttachment'), array('attachment' => $value['attachment'], 'schedulable' => $params['id'] )); 171 } 172 } 150 173 151 174 //TODO: Remover apos suporte a deepness na api … … 172 195 } 173 196 $result[$i]['participants'] = $participants; 174 } 197 198 $attachmentRelation = Controller::find( array( 'concept' => 'schedulableToAttachment' ) , false ,array( 'filter' => array('=', 'schedulable' , $v['id']) )); 199 if(is_array($attachmentRelation)){ 200 $attachments = array(); 201 foreach($attachmentRelation as $key => $value) 202 if(isset($value['attachment']) || !!$value['attachment']) 203 $attachments[$key] = $value['attachment']; 204 //Pega os anexos sem source 205 $result[$i]['attachments'] = Controller::find( array( 'concept' => 'attachment' ) , array('id', 'name', 'type', 'size') ,array( 'filter' => array('IN', 'id' , $attachments) )); 206 } 207 208 } 175 209 176 210 } … … 294 328 } 295 329 } 330 331 public function decodeFindAttachment( &$uri , &$result , &$criteria , $original ){ 332 if(isset($result)) 333 foreach($result as $key => &$value) 334 $value['source'] = base64_decode($value['source']); 335 } 336 296 337 297 338 public function decodeSignatureAlarmType( &$uri , &$result , &$criteria , $original ){ … … 389 430 } 390 431 391 } 432 } 433 434 public function deleteAttachmentDependences( &$uri , &$params , &$criteria , $original ){ 435 436 if(isset($original['URI']['id'])) 437 Controller::delete(array('concept' => 'schedulableToAttachment', null , array('filter' => array('=' , 'attachment' , $original['URI']['id'])))); 438 } 392 439 393 440 public function createDefaultSignature( &$uri , &$result , &$criteria , $original ){ -
trunk/prototype/modules/calendar/interceptors/Notifications.php
r5437 r5514 8 8 { 9 9 10 /** 10 public function formatNotification(&$uri , &$params , &$data , $original){ 11 switch ($params['type']) { 12 case 'suggestion': 13 self::formatSuggestion($params); 14 break; 15 case 'suggestionResponse': 16 self::formatSuggestionResponse($params); 17 break; 18 } 19 } 20 21 22 /** 11 23 * Analisa o commit do conceito participant e encaminha cada participant para seu devido metodo de notrificação 12 24 * … … 19 31 */ 20 32 public function commitParticipant(&$uri , &$result , &$data , $original) 21 { 33 { 22 34 if(Config::regGet('noAlarm') !== false) return; //Escapa notificações caso a flag de noAlarm esteja ativa. 23 35 24 36 $organizers = array(); //Cache Organizadores 25 37 $schedulables = array(); //Cache Schedulables 26 38 27 39 foreach ($data as $i => $concept) 28 40 { … … 39 51 foreach ($schedulables[ $concept['id'] ]['participants'] as $i => $v) //salva em $organizers as informações do organizador 40 52 if(($v['isOrganizer'] === '1') && ($organizers[$concept['id']] = $v) ) break; 41 } 53 }else if($concept['concept'] === 'schedulableToAttachment') 54 { 55 $relationAttachment = Controller::find( array( 'concept' => 'schedulableToAttachment' ) , false ,array( 'filter' => array('=', 'id' , $concept['id']))); 56 57 58 59 foreach($relationAttachment as $key => $value){ 60 if(!array_key_exists('attachments',$schedulables[$value['schedulable']])) 61 $schedulables[$value['schedulable']]['attachments'] = array(); 62 63 $temp = Controller::find( array( 'concept' => 'attachment' ) , false ,array( 'filter' => array('=', 'id' , $value['attachment']))); 64 array_push($schedulables[$value['schedulable']]['attachments'] , $temp[0]); 65 } 66 } 42 67 } 43 68 44 69 if( isset( $created ) ) 45 70 { 46 $psCreated = Controller::find(array('concept' => 'participant'), false , array('deepness' => '1' , 'filter' => array('IN', 'id' , $created ))); 47 71 $psCreated = Controller::find(array('concept' => 'participant'), false , array('deepness' => '1' , 'filter' => array('IN', 'id' , $created ))); 72 foreach ($psCreated as $i => $pCreated) 48 73 { 49 74 if($pCreated['isOrganizer'] == '1') continue; //escapa organizador … … 52 77 53 78 $organizer = isset( $organizers[$pCreated['schedulable']] ) ? $organizers[ $pCreated['schedulable'] ] : self::getOrganizer( $pCreated['schedulable'] ); 54 79 80 if($pCreated['delegatedFrom'] != 0){ 81 self::participantDelegated( $pCreated , $schedulable , $organizer); 82 continue; 83 } 84 55 85 switch ($pCreated['status']) 56 86 { … … 68 98 { 69 99 $psUpdated = Controller::find(array('concept' => 'participant'), false , array('deepness' => '1' , 'filter' => array('IN', 'id' , $updated ))); 70 71 { 100 foreach ($psUpdated as $i => $pUpdated) 101 { 72 102 if($pUpdated['isOrganizer'] == '1') continue; //escapa organizador 73 103 $schedulable = isset( $schedulables[$pUpdated['schedulable']] ) ? $schedulables[ $pUpdated['schedulable'] ] : Controller::read( array('concept' => 'schedulable', 'id' => $pUpdated['schedulable']) , false , array('deepness' => '2')); … … 77 107 if(($v['isOrganizer'] === '1') && ($organizer = $v) ) break; 78 108 79 80 if( $pUpdated['status'] != STATUS_UNANSWERED) 81 self::participantStatusChange( $pUpdated['id'] , $schedulable , $organizer , $pUpdated['status'] ); 109 if($pUpdated['delegatedFrom'] != 0){ 110 self::participantDelegatedStatusChange( $pUpdated , $schedulable , $organizer , $pUpdated['status'] ); 111 }else if( $pUpdated['status'] != STATUS_UNANSWERED && $pUpdated['status'] != STATUS_DELEGATED) 112 self::participantStatusChange( $pUpdated['id'] , $schedulable , $organizer , $pUpdated['status'] ); 82 113 } 83 114 } 84 115 } 85 86 87 /** 88 * Monta o email de convite que sera enviado ao participant 89 * 90 * @license http://www.gnu.org/copyleft/gpl.html GPL 91 * @author Consórcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br) 92 * @sponsor Caixa Econômica Federal 93 * @author Cristiano Corrêa Schmidt 94 * @return void 95 * @access public 96 */ 97 public static function participantCreated( &$partID , &$schedulable ) 98 { 116 117 public function formatSuggestion(&$params){ 118 119 $schedulable = Controller::read( array( 'concept' => 'schedulable' , 'id' => $params['schedulable'] ) , null , array('deepness' => '2') ) ; 120 121 foreach ($schedulable['participants'] as $i => $v) //salva em $organizer as informações do organizador 122 if(($v['isOrganizer'] === '1') && ($organizer = $v) ) break; 123 124 $method = 'COUNTER'; 125 $notificationType = 'Sugestão de horário'; 126 $part = 'other'; 127 128 $schedulableReference = $schedulable; 129 130 $referenceSuggestion = array( 'startTime' => $params['startTime'], 131 'endTime' => $params['endTime'], 132 'allDay' => $params['allDay'] 133 ); 134 $schedulable = array_merge($schedulable, $referenceSuggestion); 135 136 self::mountStruture(false, $schedulable, false , $data, $subject, $ical, $part, $method, $notificationType); 137 138 139 $timezone = new DateTimeZone('UTC'); 140 $sTime = new DateTime( '@'.(int)($schedulableReference['startTime'] / 1000) , $timezone ); 141 $eTime = new DateTime( '@'.(int)($schedulableReference['endTime'] / 1000) , $timezone ); 142 143 if(isset($schedulableReference['timezone'])) 144 { 145 $sTime->setTimezone(new DateTimeZone($schedulableReference['timezone'])); 146 $eTime->setTimezone(new DateTimeZone($schedulableReference['timezone'])); 147 } 148 149 $data['nowStartDate'] = date_format( $sTime , 'd/m/Y'); 150 $data['nowStartTime'] = ($schedulableReference['allDay']) ? '' : date_format( $sTime , 'H:i'); 151 $data['nowEndDate'] = date_format( $eTime , 'd/m/Y'); 152 $data['nowEndTime'] = ($schedulableReference['allDay']) ? '' : date_format( $eTime , 'H:i'); 153 $data['userRequest'] = Config::me('uid'); 154 155 $params['attachments'][] = $ical; 156 $params['isHtml'] = true; 157 $params['body'] = parseTPL::load_tpl( $data ,ROOTPATH.'/modules/calendar/templates/notify_suggestion_body.tpl'); 158 $params['subject'] = parseTPL::load_tpl( $subject ,ROOTPATH.'/modules/calendar/templates/notify_subject.tpl');; 159 $params['from'] = Config::me('mail'); 160 $params['to'] = $organizer['user']['mail']; 161 162 } 163 164 public function formatSuggestionResponse(&$params){ 165 $schedulable = $params['schedulable']; 166 foreach ($schedulable['participants'] as $i => $v) {//salva em $organizer as informações do organizador 167 if($v['isOrganizer'] === '1') $organizer = $v; 168 if($v['user']['mail'] == Config::me('mail')) $me = $v; 169 } 170 $method = 'DECLINECOUNTER'; 171 $notificationType = 'Sugestão de horário'; 172 $part = 'other'; 173 174 $schedulable['participants'] = array(); 175 array_push($schedulable['participants'], $me, $organizer); 176 177 self::mountStruture(false, $schedulable, false , $data, $subject, $ical, $part, $method, $notificationType); 178 179 if($params['status'] == 'DECLINECOUNTER') 180 $data['status'] = 'não pode ser aceito'; 181 182 $params['attachments'][] = $ical; 183 $params['isHtml'] = true; 184 $params['body'] = parseTPL::load_tpl( $data ,ROOTPATH.'/modules/calendar/templates/notify_suggestion_response_body.tpl'); 185 $params['subject'] = parseTPL::load_tpl( $subject ,ROOTPATH.'/modules/calendar/templates/notify_subject.tpl');; 186 $params['to'] = $params['from']; 187 $params['from'] = Config::me('mail'); 188 } 189 190 191 public static function _getAttendeeById($attendeId, $schedulable){ 192 foreach ($schedulable['participants'] as $id => $dv) 193 if($dv['id'] == $attendeId ) 194 return $dv; 195 } 196 197 /** 198 * Prepara para criação de email de delegação 199 * 200 * @license http://www.gnu.org/copyleft/gpl.html GPL 201 * @author Consórcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br) 202 * @sponsor Caixa Econômica Federal 203 * @author Adriano Coutinho da Silva 204 * @return void 205 * @access public 206 */ 207 public static function participantDelegated( &$partID , &$schedulable , &$organizer){ 208 209 $delegatedParams = array(); 210 211 $delegatedFrom = self::_getAttendeeById($partID['delegatedFrom'], $schedulable); 212 $delegatedParams['delegatedFrom'] = $delegatedFrom['user']['uid']; 213 214 self::participantCreated( $partID['id'] , $schedulable , STATUS_DELEGATED, $delegatedParams ); 215 216 $delegatedTo = self::_getAttendeeById($partID['id'], $schedulable); 217 $delegatedParams['delegated'] = $delegatedTo['user']['uid']; 218 219 self::participantStatusChange( $partID['delegatedFrom'] , $schedulable , $organizer , STATUS_DELEGATED, $delegatedParams ); 220 } 221 222 /** 223 * Monta o email de resposta que sera enviado ao delegatedFrom 224 * 225 * @license http://www.gnu.org/copyleft/gpl.html GPL 226 * @author Consórcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br) 227 * @sponsor Caixa Econômica Federal 228 * @author Cristiano Corrêa Schmidt 229 * @return void 230 * @access public 231 */ 232 public static function participantDelegatedStatusChange( &$partID , &$schedulable, $organizer, &$type = false){ 233 234 $delegatedParams = array(); 235 236 $delegated = self::_getAttendeeById($partID['id'], $schedulable); 237 $delegatedParams['delegated'] = $delegated['user']['uid']; 238 239 switch($partID['status']){ 240 case STATUS_ACCEPTED: 241 $delegatedParams['status'] = 'aceitou'; 242 break; 243 case STATUS_TENTATIVE: 244 $delegatedParams['status'] = 'marcou como tentativa'; 245 break; 246 case STATUS_CANCELLED: 247 $delegatedParams['status'] = 'rejeitou'; 248 break; 249 case STATUS_DELEGATED: 250 $delegatedParams['status'] = 'delegou para um novo participante'; 251 break; 252 } 253 //notifica o organizador a resposta do delegado 254 self::participantStatusChange( $partID['delegatedFrom'] , $schedulable , $organizer , $type, $delegatedParams ); 255 256 $method = 'REQUEST'; 257 $notificationType = 'Resposta Delegação'; 258 $part = 'attendees'; 259 self::mountStruture($partID['delegatedFrom'], $schedulable, $type , $data, $subject, $ical, $part, $method, $notificationType ); 260 261 $data = array_merge($data, $delegatedParams); 262 263 self::sendMail($data, $ical , $part['user']['mail'] , $subject , 'notify_response_delegated_status_body'); 264 265 } 266 267 public static function mountStruture( $partID , &$schedulable, $type = false, &$data, &$subject, &$ical, &$part = false, &$method, &$notificationType, $regSet = false) { 268 269 if( (Config::regGet('ical://'.$schedulable['id'].'/'.$method) === false) || ($method == 'CANCEL') ) //Verifica se o ical ja não esta no reg 270 { 271 $schedulable['URI']['concept'] = 'schedulable'; 272 $ical['source'] = Controller::format( array( 'service' => 'iCal' ) , array($schedulable) , array('method' => $method) ); 273 $ical['type'] = 'text/calendar'; 274 $ical['name'] = 'calendar.ics'; 275 if($regSet) 276 Config::regSet('ical://'.$schedulable['id'].'/'.$method, $ical); 277 } 278 else 279 $ical = Config::regGet('ical://'.$schedulable['id'].'/'.$method); 99 280 100 $part = false; 101 if( Config::regGet('ical://'.$schedulable['id'].'/REQUEST') === false ) //Verifica se o ical ja não esta no reg 102 { 103 $schedulable['URI']['concept'] = 'schedulable'; 104 $ical['source'] = Controller::format( array( 'service' => 'iCal' ) , array($schedulable) , array('method' => 'REQUEST') ); 105 $ical['type'] = 'text/calendar'; 106 $ical['name'] = 'calendar.ics'; 107 Config::regSet('ical://'.$schedulable['id'].'/REQUEST', $ical); 108 } 109 else 110 $ical = Config::regGet('ical://'.$schedulable['id'].'/REQUEST'); 111 112 $timezone = new DateTimeZone('UTC'); 113 $sTime = new DateTime( '@'.(int)($schedulable['startTime'] / 1000) , $timezone ); 114 $eTime = new DateTime( '@'.(int)($schedulable['endTime'] / 1000) , $timezone ); 281 $timezone = new DateTimeZone('UTC'); 282 $sTime = new DateTime( '@'.(int)($schedulable['startTime'] / 1000) , $timezone ); 283 $eTime = new DateTime( '@'.(int)($schedulable['endTime'] / 1000) , $timezone ); 115 284 116 117 118 119 120 285 if(isset($schedulable['timezone'])) 286 { 287 $sTime->setTimezone(new DateTimeZone($schedulable['timezone'])); 288 $eTime->setTimezone(new DateTimeZone($schedulable['timezone'])); 289 } 121 290 122 $attList = '<UL> '; 123 foreach ($schedulable['participants'] as $i => $v) 124 { 125 if($part === false && $v['id'] == $partID) 126 $part = $v; 127 128 $attList .= ' <LI> '. (isset($v['user']['name']) ? $v['user']['name'] : $v['user']['mail']) ; 129 } 130 $attList .= '</UL>'; 131 132 $data = array( 'startDate' => date_format( $sTime , 'd/m/Y') , 291 $data = array( 'startDate' => date_format( $sTime , 'd/m/Y') , 133 292 'startTime' => ($schedulable['allDay']) ? '' : date_format( $sTime , 'H:i') , 134 293 'endDate' => date_format( $eTime , 'd/m/Y') , … … 136 295 'eventTitle' => $schedulable['summary'], 137 296 'eventLocation' => $schedulable['location'], 138 'timezone' => ($schedulable['timezone']) ? $schedulable['timezone'] : 'UTC' , 139 'participants' => $attList); 140 141 $subject['notificationType'] = 'Convite de Calendario'; 142 $subject['eventTitle'] = mb_convert_encoding($schedulable['summary'],'ISO-8859-1','ISO-8859-1,UTF-8'); 143 $subject['startDate'] = date_format( $sTime , 'd/m/Y'); 144 $subject['startTime'] = ($schedulable['allDay']) ? '' : date_format( $sTime , 'H:i'); 145 $subject['endDate'] = date_format( $eTime , 'd/m/Y'); 146 $subject['endTime'] = ($schedulable['allDay']) ? '' : date_format( $eTime , 'H:i'); 147 $subject['participant'] = Config::me('uid'); 148 149 self::sendMail($data, $ical , $part['user']['mail'] , $subject , 'notify_create_body'); 297 'timezone' => ($schedulable['timezone']) ? $schedulable['timezone'] : 'UTC'); 298 $temp = $part; 299 $part = false; 300 switch($temp){ 301 case 'attendees': 302 $attList = '<UL> '; 303 foreach ($schedulable['participants'] as $i => $v) 304 { 305 if($part === false && $v['id'] == $partID) 306 $part = $v; 307 308 $attList .= ' <LI> '. (isset($v['user']['name']) ? $v['user']['name'] : $v['user']['mail']) ; 309 } 310 $attList .= '</UL>'; 311 $data['participants'] = $attList; 312 break; 313 case 'me': 314 $part = self::_getAttendeeById($partID, $schedulable); 315 $data['participant'] = isset($part['user']['name']) ? $part['user']['name'] : $part['user']['mail']; 316 break; 317 case 'othersAttendees': 318 $data['participants'] = '<UL> '; 319 foreach ($schedulable['participants'] as $ii => $participant){ 320 if(Config::me('mail') !== $participant['user']['mail']) 321 $part[] = $participant['user']['mail']; 322 323 $data['participants'] .= ' <LI> '. (isset($participant['user']['name']) ? $participant['user']['name'] : $participant['user']['mail']) ; 324 } 325 break; 326 } 327 $subject['notificationType'] = $notificationType; 328 $subject['eventTitle'] = mb_convert_encoding($schedulable['summary'],'ISO-8859-1','ISO-8859-1,UTF-8'); 329 $subject['startDate'] = date_format( $sTime , 'd/m/Y'); 330 $subject['startTime'] = ($schedulable['allDay']) ? '' : date_format( $sTime , 'H:i'); 331 $subject['endDate'] = date_format( $eTime , 'd/m/Y'); 332 $subject['endTime'] = ($schedulable['allDay']) ? '' : date_format( $eTime , 'H:i'); 333 $subject['participant'] = Config::me('uid'); 334 } 335 336 337 /** 338 * Monta o email de convite que sera enviado ao participant 339 * 340 * @license http://www.gnu.org/copyleft/gpl.html GPL 341 * @author Consórcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br) 342 * @sponsor Caixa Econômica Federal 343 * @author Cristiano Corrêa Schmidt 344 * @return void 345 * @access public 346 */ 347 public static function participantCreated( &$partID , &$schedulable, $type = false, $delegatedParams = false) 348 { 349 $method = 'REQUEST'; 350 $notificationType = 'Convite de Calendario'; 351 $part = 'attendees'; 352 self::mountStruture($partID, $schedulable, $type , $data, $subject, $ical, $part, $method, $notificationType, true); 353 354 if($delegatedParams) 355 $data = array_merge($data, $delegatedParams); 356 357 self::sendMail($data, $ical , $part['user']['mail'] , $subject , !$delegatedParams ? 'notify_create_body' : 'notify_create_delegated_body' ); 150 358 151 359 } … … 161 369 * @access public 162 370 */ 163 public static function participantStatusChange( &$partID , &$schedulable , &$organizer , $type ) 164 { 165 $part = false; 166 167 foreach ($schedulable['participants'] as $i => $v) //salva em $part as informações do participant a ser notificado 168 if(($v['id'] == $partID) && ($part = $v) ) break; 169 170 if( Config::regGet('ical://'.$schedulable['id'].'/REPLY') === false ) //Verifica se o ical ja não esta no reg 171 { 172 $schedulable['URI']['concept'] = 'schedulable'; 173 $ical['source'] = Controller::format( array( 'service' => 'iCal' ) , array($schedulable) , array('method' => 'REPLY' , 'participant' => $partID) ); 174 $ical['type'] = 'text/calendar'; 175 $ical['name'] = 'calendar.ics'; 176 Config::regSet('ical://'.$schedulable['id'].'/REPLY', $ical); 177 } 178 else 179 $ical = Config::regGet('ical://'.$schedulable['id'].'/REPLY'); 180 181 182 $timezone = new DateTimeZone('UTC'); 183 $sTime = new DateTime( '@'.(int)($schedulable['startTime'] / 1000) , $timezone ); 184 $eTime = new DateTime( '@'.(int)($schedulable['endTime'] / 1000) , $timezone ); 185 186 if(isset($schedulable['timezone'])) 187 { 188 $sTime->setTimezone(new DateTimeZone($schedulable['timezone'])); 189 $eTime->setTimezone(new DateTimeZone($schedulable['timezone'])); 190 } 191 192 $data = array('startDate' => date_format( $sTime , 'd/m/Y') , 193 'startTime' => ($schedulable['allDay']) ? '' : date_format( $sTime , 'H:i') , 194 'endDate' => date_format( $eTime , 'd/m/Y') , 195 'endTime' => ($schedulable['allDay']) ? '' : date_format( $eTime , 'H:i') , 196 'eventTitle' => $schedulable['summary'], 197 'eventLocation' => $schedulable['location'], 198 'timezone' => ($schedulable['timezone']) ? $schedulable['timezone'] : 'UTC' , 199 'participant' => (isset($part['user']['name']) ? $part['user']['name'] : $part['user']['mail']) ); 200 201 $subject['notificationType'] = 'Convite Aceito'; 202 $subject['eventTitle'] = mb_convert_encoding($schedulable['summary'],'ISO-8859-1','ISO-8859-1,UTF-8'); 203 $subject['startDate'] = date_format( $sTime , 'd/m/Y'); 204 $subject['startTime'] = ($schedulable['allDay']) ? '' : date_format( $sTime , 'H:i'); 205 $subject['endDate'] = date_format( $eTime , 'd/m/Y'); 206 $subject['endTime'] = ($schedulable['allDay']) ? '' : date_format( $eTime , 'H:i'); 207 $subject['participant'] = Config::me('uid'); 208 371 public static function participantStatusChange( &$partID , &$schedulable , &$organizer , $type, $delegatedParams = false ) 372 { 373 $method = 'REPLY'; 374 $notificationType = 'Convite Aceito'; 375 $part = 'me'; 376 377 self::mountStruture($partID, $schedulable, $type , $data, $subject, $ical, $part, $method, $notificationType, true ); 378 379 if($delegatedParams){ 380 $data = array_merge($data, $delegatedParams); 381 $tplDelegated = 'notify_delegated_status_body'; 382 } 383 209 384 switch($type) 210 385 { 211 386 case STATUS_ACCEPTED: 212 $tpl = 'notify_accept_body';387 $tpl = !$delegatedParams ? 'notify_accept_body' : $tplDelegated; 213 388 $subject['notificationType'] = 'Convite Aceito'; 214 389 break; 215 case STATUS_TEN ATIVE:216 $tpl = 'notify_attempt_body';390 case STATUS_TENTATIVE: 391 $tpl = !$delegatedParams ? 'notify_attempt_body' : $tplDelegated; 217 392 $subject['notificationType'] = 'Convite aceito provisoriamente'; 218 393 break; 219 394 case STATUS_CANCELLED: 220 $tpl = 'notify_reject_body';395 $tpl = !$delegatedParams ? 'notify_reject_body' : $tplDelegated; 221 396 $subject['notificationType'] = 'Convite rejeitado'; 397 break; 398 case STATUS_DELEGATED: 399 if($delegatedParams) 400 $data = array_merge($data, $delegatedParams); 401 $tpl = 'notify_delegated_body'; 402 $subject['notificationType'] = 'Convite delegado'; 222 403 break; 223 404 … … 264 445 if((Config::regGet('noAlarm') === false) && (self::futureEvent( $schedulable['startTime'] , $schedulable['rangeEnd']))) 265 446 { 266 $schedulable['URI']['concept'] = 'schedulable'; 267 $timezone = new DateTimeZone('UTC'); 268 $sTime = new DateTime( '@'.(int)($schedulable['startTime'] / 1000) , $timezone ); 269 $eTime = new DateTime( '@'.(int)($schedulable['endTime'] / 1000) , $timezone ); 270 271 if(isset($schedulable['timezone'])) 272 { 273 $sTime->setTimezone(new DateTimeZone($schedulable['timezone'])); 274 $eTime->setTimezone(new DateTimeZone($schedulable['timezone'])); 275 } 276 277 $data = array('startDate' => date_format( $sTime , 'd/m/Y') , 278 'startTime' => ($schedulable['allDay']) ? '' : date_format( $sTime , 'H:i') , 279 'endDate' => date_format( $eTime , 'd/m/Y') , 280 'endTime' => ($schedulable['allDay']) ? '' : date_format( $eTime , 'H:i') , 281 'eventTitle' => $schedulable['summary'], 282 'eventLocation' => $schedulable['location'], 283 'timezone' => ($schedulable['timezone']) ? $schedulable['timezone'] : 'UTC'); 284 285 286 $ical['source'] = Controller::format( array( 'service' => 'iCal' ) , array($schedulable) , array('method' => 'CANCEL')); 287 $ical['type'] = 'text/calendar'; 288 $ical['name'] = 'calendar.ics'; 289 290 foreach ($schedulable['participants'] as $ii => $participant) 291 if(Config::me('mail') !== $participant['user']['mail']) 292 $to[] = $participant['user']['mail']; 293 294 $subject['notificationType'] = 'Cancelamento de Calendario'; 295 $subject['eventTitle'] = mb_convert_encoding($schedulable['summary'],'ISO-8859-1','ISO-8859-1,UTF-8'); 296 $subject['startDate'] = date_format( $sTime , 'd/m/Y'); 297 $subject['startTime'] = ($schedulable['allDay']) ? '' : date_format( $sTime , 'H:i'); 298 $subject['endDate'] = date_format( $eTime , 'd/m/Y'); 299 $subject['endTime'] = ($schedulable['allDay']) ? '' : date_format( $eTime , 'H:i'); 300 $subject['participant'] = Config::me('uid'); 447 $method = 'CANCEL'; 448 $notificationType = 'Cancelamento de Calendario'; 449 $part = 'othersAttendees'; 450 self::mountStruture($uri['id'], $schedulable, false , $data, $subject, $ical, $part, $method, $notificationType ); 301 451 302 if(count($ to) > 0)303 self::sendMail($data, $ical , implode(',' , $ to) ,$subject, 'notify_cancel_body');452 if(count($part) > 0) 453 self::sendMail($data, $ical , implode(',' , $part) ,$subject, 'notify_cancel_body'); 304 454 } 305 455 } … … 323 473 if((Config::regGet('noAlarm') === false) && (self::futureEvent( $schedulable['startTime'] , $schedulable['rangeEnd']))) 324 474 { 325 $schedulable['URI']['concept'] = 'schedulable'; 326 $timezone = new DateTimeZone('UTC'); 327 $sTime = new DateTime( '@'.(int)($schedulable['startTime'] / 1000) , $timezone ); 328 $eTime = new DateTime( '@'.(int)($schedulable['endTime'] / 1000) , $timezone ); 329 330 if(isset($schedulable['timezone'])) 331 { 332 $sTime->setTimezone(new DateTimeZone($schedulable['timezone'])); 333 $eTime->setTimezone(new DateTimeZone($schedulable['timezone'])); 334 } 335 336 $data = array('startDate' => date_format( $sTime , 'd/m/Y') , 337 'startTime' => ($schedulable['allDay']) ? '' : date_format( $sTime , 'H:i') , 338 'endDate' => date_format( $eTime , 'd/m/Y') , 339 'endTime' => ($schedulable['allDay']) ? '' : date_format( $eTime , 'H:i') , 340 'eventTitle' => $schedulable['summary'], 341 'eventLocation' => $schedulable['location'], 342 'timezone' => ($schedulable['timezone']) ? $schedulable['timezone'] : 'UTC'); 343 344 $ical['source'] = Controller::format( array( 'service' => 'iCal' ) , array($schedulable) , array('method' => 'CANCEL')); 345 $ical['type'] = 'text/calendar'; 346 $ical['name'] = 'calendar.ics'; 347 348 $subject['notificationType'] = 'Cancelamento de Calendario'; 349 $subject['eventTitle'] = mb_convert_encoding($schedulable['summary'],'ISO-8859-1','ISO-8859-1,UTF-8'); 350 $subject['startDate'] = date_format( $sTime , 'd/m/Y'); 351 $subject['startTime'] = ($schedulable['allDay']) ? '' : date_format( $sTime , 'H:i'); 352 $subject['endDate'] = date_format( $eTime , 'd/m/Y'); 353 $subject['endTime'] = ($schedulable['allDay']) ? '' : date_format( $eTime , 'H:i'); 354 $subject['participant'] = Config::me('uid'); 355 356 self::sendMail($data, $ical , $participant['user']['mail'] , $subject , 'notify_cancel_body'); 475 $method = 'CANCEL'; 476 $notificationType = 'Cancelamento de Calendario'; 477 $part = 'others'; 478 self::mountStruture(false, $schedulable, false , $data, $subject, $ical, $part, $method, $notificationType ); 479 480 self::sendMail($data, $ical , $participant['user']['mail'] , $subject , 'notify_cancel_body'); 357 481 } 358 482 } … … 369 493 */ 370 494 public function updateEvent( &$uri , &$params , &$criteria , $original ) 371 { 372 373 $schedulableOld = Controller::read( array( 'concept' => 'schedulable' , 'id' => $uri['id'] ) , null , array('deepness' => '2') ) ; 495 { 496 $schedulableOld = Controller::find( array( 'concept' => 'schedulable' , 'id' => $uri['id'] ) , null , array('deepness' => '2') ) ; 374 497 $schedulable = $schedulableOld; 375 498 $alt = false; 376 377 499 378 500 foreach ($params as $i => $v) //Verifica se ouve alteração no evento 379 501 if( isset( $schedulableOld[$i] ) && $schedulableOld[$i] != $v && $i != 'participants') … … 384 506 385 507 if ( ($alt === true) && (Config::regGet('noAlarm') === false) && (self::futureEvent($schedulable['startTime'], $schedulable['rangeEnd'])) ) 386 { 387 $schedulable['URI']['concept'] = 'schedulable'; 388 $ical['source'] = Controller::format(array('service' => 'iCal'), array($schedulable), array('method' => 'REQUEST')); 389 $ical['type'] = 'text/calendar'; 390 $ical['name'] = 'calendar.ics'; 391 392 $timezone = new DateTimeZone('UTC'); 393 $sTime = new DateTime('@' . (int) ($schedulable['startTime'] / 1000), $timezone); 394 $eTime = new DateTime('@' . (int) ($schedulable['endTime'] / 1000), $timezone); 395 396 if (isset($schedulable['timezone'])) { 397 $sTime->setTimezone(new DateTimeZone($schedulable['timezone'])); 398 $eTime->setTimezone(new DateTimeZone($schedulable['timezone'])); 399 } 400 ///Montando lista de participantes 401 $attList = '<UL> '; 402 foreach ($schedulable['participants'] as $ii => $participant) 403 $attList .= ' <LI> ' . (isset($participant['user']['name']) ? $participant['user']['name'] : $participant['user']['mail']); 404 $attList .= ' </UL>'; 405 ///////////////////////// 406 407 $data = array('startDate' => date_format($sTime, 'd/m/Y'), 408 'startTime' => ($schedulable['allDay']) ? '' : date_format($sTime, 'H:i'), 409 'endDate' => date_format($eTime, 'd/m/Y'), 410 'endTime' => ($schedulable['allDay']) ? '' : date_format($eTime, 'H:i'), 411 'eventTitle' => $schedulable['summary'], 412 'eventLocation' => $schedulable['location'], 413 'timezone' => ($schedulable['timezone']) ? $schedulable['timezone'] : 'UTC', 414 'participants' => $attList 415 ); 416 417 418 foreach ($schedulable['participants'] as $ii => $participant) 419 if (Config::me('mail') !== $participant['user']['mail']) 420 $to[] = $participant['user']['mail']; 421 422 $subject['notificationType'] = 'Modificação de Calendario'; 423 $subject['eventTitle'] = mb_convert_encoding($schedulable['summary'],'ISO-8859-1','ISO-8859-1,UTF-8'); 424 $subject['startDate'] = date_format($sTime, 'd/m/Y'); 425 $subject['startTime'] = ($schedulable['allDay']) ? '' : date_format($sTime, 'H:i'); 426 $subject['endDate'] = date_format($eTime, 'd/m/Y'); 427 $subject['endTime'] = ($schedulable['allDay']) ? '' : date_format($eTime, 'H:i'); 428 $subject['participant'] = Config::me('uid'); 429 430 if ( isset($to) && count($to) > 0) 431 self::sendMail($data, $ical, implode(',', $to), $subject, 'notify_modify_body'); 508 { 509 $method = 'REQUEST'; 510 $notificationType = 'Modificação de Calendario'; 511 $part = 'othersAttendees'; 512 self::mountStruture($partID, $schedulable, $type , $data, $subject, $ical, $part, $method, $notificationType); 513 514 if ( isset($part) && count($part) > 0) 515 self::sendMail($data, $ical, implode(',', $part), $subject, 'notify_modify_body'); 432 516 } 433 517 } -
trunk/prototype/modules/calendar/js/calendar.codecs.js
r5468 r5514 29 29 this.preferenceIds = pref.ids; 30 30 } 31 } 32 33 constantsParticipant = { 34 'o' : 'organization', 35 'w' : 'write', 36 'p' : 'participationRequired', 37 'i' : 'inviteGuests', 38 'r' : 'read' 31 39 } 32 40 … … 333 341 }); 334 342 343 DataLayer.codec( "suggestion", "duration", { 344 345 decoder: function( evtObj ){ 346 if( notArray = $.type(evtObj) !== "array" ) 347 evtObj = [ evtObj ]; 348 349 350 351 var meAttendee = function(attendees){ 352 for(var i = 0; i < attendees.length; i++) 353 if(DataLayer.get('participant', attendees[i]).user == User.me.id) 354 return attendee; 355 }; 356 357 var res = $.map(evtObj, function( form ){ 358 return { 359 participant : meAttendee(form.attendee), 360 startTime: Timezone.getDateUTC(Date.parseExact(form.startDate + (!!form.allDay ? " 00:00": " "+$.trim(form.startHour)) , formatString ), tzId).getTime(), 361 endTime: parseInt(Timezone.getDateUTC(Date.parseExact(form.endDate + ( !!form.allDay ? " 00:00": " "+$.trim(form.endHour)), formatString ), tzId).getTime()) + (!!form.allDay ? 86400000 : 0) , 362 allDay: ( !!form.allDay ? 1 : 0 ), 363 schedulable: form.idEvent 364 } 365 }); 366 367 368 return notArray ? res[0] : res; 369 }, 370 371 encoder: function( evtObj ){} 372 373 }); 374 375 DataLayer.codec( "attachment", "detail", { 376 377 decoder: function(evtObj){ 378 379 if( notArray = $.type(evtObj) !== "array" ) 380 evtObj = [ evtObj ]; 381 382 var res = $.map(evtObj, function( form){ 383 return [$.map(form.files , function( files){ 384 return { source: files }; 385 })]; 386 }); 387 return notArray ? res[0] : res; 388 }, 389 390 encoder: function(){} 391 392 393 }); 394 335 395 DataLayer.codec( "schedulable", "preview", { 336 396 … … 348 408 id: form.idEvent, 349 409 calendar: form.calendar, 350 participants : [{ 351 user: User.me.id, 352 status: form.status, 353 id: form.meId, 354 isOrganizer: 0, 355 alarms: typeof(form.alarmTime) != 'undefined' ? 356 $.map( form.alarmTime || [], function( alarmTime, i ){ 357 358 if( alarmTime === "" ) 359 return( null ); 360 361 return !!form.alarmId[i] ? 362 { type: form.alarmType[i], unit: form.alarmUnit[i], time: form.alarmTime[i], id: form.alarmId[i] } : 363 { type: form.alarmType[i],unit: form.alarmUnit[i], time: form.alarmTime[i] }; 364 }) : [] 365 }] 410 participants : $.map(form.attendee, function( attendee, i ){ 411 if(isNaN(attendee)){ 412 return{ 413 id: attendee, 414 acl: form.attendeeAcl[i], 415 delegatedFrom: !!form.delegatedFrom[i] ? form.delegatedFrom[i] : 0, 416 isOrganizer: (form.attendee_organizer == attendee ? 1 : 0 ), 417 isExternal: !!parseInt(form.attendeeType[i]) ? 1 : 0, 418 acl: form.attendeeAcl[i].replace('o', '') 419 }; 420 }else{ 421 if(DataLayer.get('participant', attendee).user == User.me.id){ 422 var me = { 423 user: User.me.id, 424 status: form.status, 425 id: attendee, 426 isOrganizer: 0, 427 receiveNotification : (!!form.receiveNotification ? 1 : 0), 428 alarms: typeof(form.alarmTime) != 'undefined' ? 429 $.map( form.alarmTime || [], function( alarmTime, i ){ 430 431 if( alarmTime === "" ) 432 return( null ); 433 434 return !!form.alarmId[i] ? 435 { type: form.alarmType[i], unit: form.alarmUnit[i], time: form.alarmTime[i], id: form.alarmId[i] } : 436 { type: form.alarmType[i],unit: form.alarmUnit[i], time: form.alarmTime[i] }; 437 }) : [] 438 }; 439 440 if(form.startDate){ 441 var tzId = DataLayer.get('schedulable', form.idEvent).timezone || User.preferences.timezone, 442 formatString = ( typeof form.allDay !== "undefined" && !!form.allDay )? pref.dateFormat+" HH:mm" : pref.dateFormat + " " + pref.hourFormat; 443 444 DataLayer.put('notification', { 445 participant: me.id, 446 type: 'suggestion', 447 startTime: Timezone.getDateUTC(Date.parseExact(form.startDate + (!!form.allDay ? " 00:00": " "+$.trim(form.startHour)) , formatString ), tzId).getTime(), 448 endTime: parseInt(Timezone.getDateUTC(Date.parseExact(form.endDate + ( !!form.allDay ? " 00:00": " "+$.trim(form.endHour)), formatString ), tzId).getTime()) + (!!form.allDay ? 86400000 : 0) , 449 allDay: ( !!form.allDay ? 1 : 0 ), 450 schedulable: form.idEvent 451 }); 452 453 } 454 return me; 455 }else return(null); 456 }; 457 }) 366 458 } 367 459 }); 368 369 460 return notArray ? res[0] : res; 370 461 }, … … 381 472 statusLabels = [ '', 'accepted', 'tentative', 'cancelled', 'unanswered', 'delegated' ]; 382 473 474 var delegateAttendee = {}; 475 383 476 for( var i = 0; i < statusLabels.length; i++ ) 384 477 statusParticipants[ statusLabels[i] ] = 0; 385 386 var isOrganizer = 1;387 478 388 479 var res = $.map(evtObj, function( objEvent ){ 389 480 390 var participantInfo = {}, me = DataLayer.copy(User.me); 481 var participantInfo = {}, delegatedFrom = {}, me = DataLayer.copy(User.me); 482 483 var constantAcl = function(acl){ 484 var returns = {}; 485 for (var i in constantsParticipant){ 486 returns[constantsParticipant[i]] = acl.indexOf(i) >= 0 ? true : false 487 } 488 return returns; 489 }; 391 490 392 491 return { … … 406 505 endHour: dateCalendar.formatDate(Timezone.setDateTimezone(new Date(parseInt(objEvent.endTime)), objEvent.timezone, objEvent.calendar), User.preferences.hourFormat), 407 506 allDay: !!parseInt( objEvent.allDay ), 408 // attachments: this.decode( "attachment:detail", form ), 507 attachments: $.map(objEvent.attachments || [], function( attachment, i ){ 508 var attach = DataLayer.get('schedulableToAttachment', attachment, false); 509 attach.name = attach.name.length < 10 ? attach.name : ( attach.name.substr(0, 6) + attach.name.substr( attach.name.length-4, attach.name.length)); 510 511 return attach; 512 }), 409 513 attendee: $.map(objEvent.participants || [], function( participant, i ){ 514 515 if(delegateAttendee[participant]) 516 return(null); 410 517 411 518 var attend = DataLayer.get('participant', participant); … … 416 523 if( attend.user.id === me.id ){ 417 524 participantInfo.user = { 525 id: attend.id, 418 526 status : attend.status, 527 delegatedFrom: attend.delegatedFrom, 528 acl: attend.acl, 529 receiveNotification : attend.receiveNotification, 419 530 alarms : $.map(attend.alarms || [], function( alarm ){ 420 531 return DataLayer.get('alarm', alarm); … … 422 533 }; 423 534 me.id = attend.id; 424 535 return(null); 425 536 }; 426 537 … … 429 540 name: attend.user.name != 'false' ? attend.user.name : '', 430 541 mail: attend.user.mail, 431 isExternal: attend.isExternal 542 status : attend.status, 543 isExternal: attend.isExternal, 544 acl: attend.acl, 545 delegatedFrom: attend.delegatedFrom 432 546 }; 433 547 548 if(!!parseInt(attend.delegatedFrom)){ 549 delegatedFrom[attend.delegatedFrom] = DataLayer.copy(person); 550 return(null); 551 } 552 434 553 if( !!parseInt(attend.isOrganizer )){ 435 isOrganizer = ((attend.user.id == User.me.id) || (!!!attend.user)) ? 1 : 0;436 554 participantInfo.organizer = DataLayer.copy(person); 437 555 return(null); … … 441 559 }), 442 560 organizer: participantInfo.organizer || me, 443 alarms: !!participantInfo.user ? participantInfo.user.alarms : [], 444 status: !!participantInfo.user ? participantInfo.user.status : 1, 445 me: me, 446 isOrganizer: isOrganizer, 561 alarms: !!participantInfo.user ? participantInfo.user.alarms : [], 562 status: !!participantInfo.user ? participantInfo.user.status : 1, 563 acl: !!participantInfo.user ? constantAcl(participantInfo.user.acl) : constantAcl('rowi'), 564 me: !!participantInfo.user ? DataLayer.merge(participantInfo.user, me) : DataLayer.merge(me, {acl: 'rowi', delegatedFrom: 0, receiveNotification: 1}), 565 delegatedFrom: delegatedFrom, 447 566 statusParticipants: statusParticipants 448 567 }; 449 }); 450 568 }); 451 569 return notArray ? res[0] : res; 452 570 } … … 485 603 description: form.description, 486 604 timezone: tzId, 605 attachments: $.map(form.attachment || [], function( attachment, i ){ 606 return {attachment: attachment} 607 }), 487 608 participants: $.map( form.attendee || [], function( attendee, i ){ 488 609 … … 495 616 if( participant.user === User.me.id ){ 496 617 return DataLayer.merge({ 497 isOrganizer: ( !i ? 1 : 0 ), 618 id: attendee, 619 isOrganizer: (form.attendee_organizer == attendee ? 1 : 0 ), 620 acl: form.attendee_organizer == attendee ? (form.attendeeAcl[i].indexOf('o') < 0 ? form.attendeeAcl[i]+'o' : form.attendeeAcl[i]) : form.attendeeAcl[i].replace('o', ''), 498 621 alarms: participant.alarms = $.map( form.alarmTime || [], function( alarmTime, i ){ 499 622 if( alarmTime === "" ) … … 502 625 { type: form.alarmType[i],unit: form.alarmUnit[i], time: form.alarmTime[i] }; 503 626 }), 504 status: form.status505 }, !!form.idEvent ? {id: attendee} : {user: participant.user});627 status: !!form.status ? form.status : 3 628 }, form.delegatedFrom[i] != '0' ? {delegatedFrom: form.delegatedFrom[i]} : {}); 506 629 }else{ 507 return {630 return DataLayer.merge({ 508 631 id: attendee, 509 isOrganizer: ( !i ? 1 : 0 ), 510 isExternal: !!parseInt(form.attendeeType[i]) ? 1 : 0 511 }; 632 acl: form.attendeeAcl[i], 633 isOrganizer: (form.attendee_organizer == attendee ? 1 : 0 ), 634 isExternal: !!parseInt(form.attendeeType[i]) ? 1 : 0, 635 acl: form.attendee_organizer == attendee ? (form.attendeeAcl[i].indexOf('o') < 0 ? form.attendeeAcl[i]+'o' : form.attendeeAcl[i]) : form.attendeeAcl[i].replace('o', '') 636 }, form.delegatedFrom[i] != '0' ? {delegatedFrom: form.delegatedFrom[i]} : {}); 512 637 }; 513 638 }) … … 719 844 for(var i = 0; i < evt.participants.length; i++){ 720 845 attendee = DataLayer.get('participant', evt.participants[i]); 721 if(!!parseInt(attendee.isOrganizer))722 846 if(attendee.user == User.me.id) 723 return true; 724 else 725 return false; 847 return (attendee.acl.indexOf('w') >= 0 || attendee.acl.indexOf('o') >= 0 ) ? true : false; 726 848 } 727 849 } -
trunk/prototype/modules/calendar/js/helpers.js
r5510 r5514 45 45 } 46 46 */ 47 47 48 function eventDetails( objEvent, decoded, path) 48 49 { … … 69 70 */ 70 71 zebraDiscardEventDialog = false; 72 73 /** 74 ACLs do participant 75 */ 76 acl_names = { 77 'w': 'acl-white', 78 'i': 'acl-invite-guests', 79 'p': 'acl-participation-required' 80 }; 81 /** 82 * callback de participantes generico 83 */ 84 var callbackAttendee = function(){ 85 //Cria qtip de permissões pelo click do checkbox 86 var checked = false; 87 blkAddAtendee.find("li.not-attendee").addClass('hidden'); 88 89 blkAddAtendee.find("li .button").filter(".close.new").button({ 90 icons: { 91 primary: "ui-icon-close" 92 }, 93 text: false 94 }).click(function () { 95 DataLayer.remove('participant', $(this).parents('li').find('[type=checkbox]').val()); 96 $(this).parents('li').remove(); 97 if(blkAddAtendee.find(".attendee-list li").length == 1) 98 blkAddAtendee.find("li.not-attendee").removeClass('hidden'); 99 }) 100 .addClass('tiny disable ui-button-disabled ui-state-disabled') 101 .removeClass('new').end() 102 103 .filter(".delegate.new").button({ 104 icons: { 105 primary: "ui-icon-transferthick-e-w" 106 }, 107 text: false 108 }).click(function () { 109 110 if($(this).hasClass('attendee-permissions-change-button')){ 111 $(this).removeClass('attendee-permissions-change-button') 112 .find('.ui-icon-transferthick-e-w').removeClass('attendee-permissions-change').end(); 113 114 $(this).parents('li').find('input[name="delegatedFrom[]"]').val(''); 115 116 blkAddAtendee.find('.request-update').addClass('hidden'); 117 blkAddAtendee.find('.status option').toggleClass('hidden'); 118 119 120 blkAddAtendee.find('option[value=1]').attr('selected','selected').trigger('change'); 121 122 }else{ 123 blkAddAtendee.find('.delegate').removeClass('attendee-permissions-change-button'); 124 blkAddAtendee.find('.ui-icon-transferthick-e-w').removeClass('attendee-permissions-change'); 125 126 $(this).addClass('attendee-permissions-change-button') 127 .find('.ui-icon-transferthick-e-w').addClass('attendee-permissions-change').end(); 128 $(this).parents('li').find('input[name="delegatedFrom[]"]').val(blkAddAtendee.find('.me input[name="attendee[]"]').val()); 129 130 blkAddAtendee.find('.request-update').removeClass('hidden'); 131 if(blkAddAtendee.find('.status option.hidden').length == 1) 132 blkAddAtendee.find('.status option').toggleClass('hidden'); 133 134 blkAddAtendee.find('option[value=5]').attr('selected','selected').trigger('change'); 135 } 136 }) 137 .addClass('tiny disable ui-button-disabled ui-state-disabled') 138 .removeClass('new').end() 139 140 .filter(".edit.new").button({ 141 icons: { 142 primary: "ui-icon-key" 143 }, 144 text: false 145 }).click(function() { 146 147 if(!!!checked) 148 $(this).parents('li').find('[type=checkbox]').attr('checked', (!$(this).parent().find('[type=checkbox]').is(':checked'))).end(); 149 150 var aclsParticipant = $(this).parents('li').find('input[name="attendeeAcl[]"]').val(); 151 checked = false; 152 153 if( $('.qtip.qtip-blue.qtip-active').val() !== ''){ 154 blkAddAtendee.find('dd.attendee-list').qtip({ 155 show: {ready: true, solo: true, when: {event: 'click'}}, 156 hide: false, 157 content: { 158 text: $('<div></div>').html( DataLayer.render( 'templates/attendee_permissions.ejs', {} ) ), 159 title: { 160 text:'Permissões', 161 button: '<a class="button close" href="#">close</a>' 162 } 163 }, 164 style: {name: 'blue', tip: {corner: 'leftMiddle'}, border: {width: 4, radius: 8}, width: {min: 230, max:230}}, 165 position: { 166 corner: { 167 target: 'rightMiddle', 168 tooltip: 'leftMiddle' 169 }, 170 adjust: {x:0, y:0} 171 } 172 }) 173 .qtip("api").onShow = function(arg0) { 174 $('.qtip-active .button.close').button({ 175 icons: {primary: "ui-icon-close"}, 176 text: false 177 }) 178 .click(function(){ 179 blkAddAtendee.find('dd.attendee-list').qtip('destroy'); 180 }); 181 182 $('.qtip-active .button.save').button().click(function(){ 183 184 var acl = ''; 185 $('.qtip-active').find('[type=checkbox]:checked').each(function(i, obj) { 186 acl+= obj.value; 187 }); 188 189 blkAddAtendee.find('dd.attendee-list [type=checkbox]:checked').siblings('input[name="attendeeAcl[]"]').each(function(i, obj) { 190 obj.value = 'r'+acl; 191 }).parents('li').find('.button.edit').addClass('attendee-permissions-change-button') 192 .find('.ui-icon-key').addClass('attendee-permissions-change'); 193 194 blkAddAtendee.find('dd.attendee-list [type=checkbox]').attr('checked', false); 195 196 blkAddAtendee.find('dd.attendee-list').qtip('destroy'); 197 198 }); 199 $('.qtip-active .button.cancel').button().click(function(){ 200 blkAddAtendee.find('dd.attendee-list [type=checkbox]').attr('checked', false); 201 blkAddAtendee.find('dd.attendee-list').qtip('destroy'); 202 }); 203 204 if(aclsParticipant) 205 for(var i = 1; i < aclsParticipant.length; i++){ 206 $('.qtip-active').find('input[name="'+acl_names[aclsParticipant.charAt(i)]+'"]').attr('checked', true); 207 } 208 209 210 $('.button').button(); 211 212 }; 213 }else{ 214 if(!$('.new-event-win dd.attendee-list').find('[type=checkbox]:checked').length){ 215 blkAddAtendee.find('dd.attendee-list').qtip('destroy'); 216 }else{ 217 $('.qtip-active .button.save .ui-button-text').html('Aplicar a todos') 218 } 219 220 }; 221 }) 222 .addClass('tiny disable ui-button-disabled ui-state-disabled') 223 .removeClass('new').end() 224 225 .filter(".open-delegate.new").click(function(){ 226 if($(this).hasClass('ui-icon-triangle-1-e')){ 227 $(this).removeClass('ui-icon-triangle-1-e').addClass('ui-icon-triangle-1-s'); 228 $(this).parents('li').find('.list-delegates').removeClass('hidden'); 229 }else{ 230 $(this).removeClass('ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-e'); 231 $(this).parents('li').find('.list-delegates').addClass('hidden'); 232 } 233 234 }).removeClass('new'); 235 236 237 blkAddAtendee.find("li input[type=checkbox].new").click(function(){ 238 if(!$('.new-event-win dd.attendee-list').find('[type=checkbox]:checked').length){ 239 blkAddAtendee.find('dd.attendee-list').qtip('destroy'); 240 }else{ 241 checked = true; 242 $(this).parents('li').find('.button.edit').click(); 243 //$('.qtip-active .button.save .ui-button-text').html('Aplicar a todos') 244 } 245 246 checked = true; 247 $(this).parents('li').find('.button.edit').click(); 248 }).removeClass('new'); 249 250 UI.dialogs.addEvent.find('.attendees-list li').hover( 251 function () { 252 $(this).addClass("hover-attendee"); 253 $(this).find('.button').removeClass('disable ui-button-disabled ui-state-disabled').end() 254 .find('.attendee-options').addClass('hover-attendee'); 255 }, 256 function () { 257 $(this).removeClass("hover-attendee"); 258 $(this).find('.button').addClass('disable ui-button-disabled ui-state-disabled').end() 259 .find('.attendee-options').removeClass('hover-attendee');; 260 } 261 ); 262 263 264 } 71 265 72 266 var html = DataLayer.render( path+'templates/event_add.ejs', {event:objEvent}); … … 99 293 if(clicked == 'Descartar alterações') { 100 294 canDiscardEventDialog = true; 295 /** 296 *Remoção dos anexos do eventos caso seja cancelado a edição 297 */ 298 var ids = []; 299 $.each($('.attachment-list input'), function (i, input) { ids.push(input.value); }); 300 if(ids.length > 0) 301 DataLayer.remove('attachment', {filter: ['IN', 'id', ids]}); 302 101 303 UI.dialogs.addEvent.dialog('close'); 102 304 }else{ … … 256 458 canDiscardEventDialog = true; 257 459 258 UI.dialogs.addEvent.children( ".form-addevent").submit();460 UI.dialogs.addEvent.children().find('form.form-addevent').submit(); 259 461 UI.dialogs.addEvent.dialog("close"); 260 462 }).end() 261 463 262 464 .children(".export").click(function(){ 263 UI.dialogs.addEvent.children( ".form-export").submit();465 UI.dialogs.addEvent.children().find(".form-export").submit(); 264 466 }); 265 467 … … 293 495 }); 294 496 295 // UI.dialogs.addEvent.find('.button-add-attachment').click(function(){ 296 // var li_attach = 297 // '<li class="input_label">' + 298 // '<input type="file" name="attachments[]"" />' + 299 // '</li>'; 300 // jQuery('.attachments-list').append(li_attach); 301 // }); 302 303 var attendeeHtml = DataLayer.render( path+'templates/attendee_add.ejs', {event:objEvent}); 497 498 UI.dialogs.addEvent.find('.button.suggestion-hours').button({ 499 icons: { 500 primary: "ui-icon-clock" 501 }, 502 text: 'Sugerir horário' 503 }).click(function () { 504 $(this).siblings('input').removeAttr('disabled') 505 .end().parents().find('input[name="allDay"]').removeAttr('disabled'); 506 }); 507 508 if(objEvent.me.id == User.me.id){ 509 objEvent.me.id = DataLayer.put('participant', {user: objEvent.me.id, mail: objEvent.me.mail }); 510 objEvent.organizer.id = objEvent.me.id; 511 } 512 513 var attendeeHtml = DataLayer.render( path+'templates/attendee_add.ejs', {event:objEvent}); 304 514 305 515 // load template of attendees 306 516 var blkAddAtendee = UI.dialogs.addEvent.find('#calendar_addevent_details6').append(attendeeHtml); 307 308 blkAddAtendee.find('li.attendee .button').addClass('small '+ (objEvent.isOrganizer == 1 ? '' : 'hidden')).button({text:false, icons: {primary:'ui-icon-close'}}).click(function () { 309 DataLayer.remove('participant', $(this).parent().find('[type=checkbox]').val()); 310 $(this).parent().remove(); 311 }); 517 if(objEvent.attendee.length) 518 callbackAttendee(); 519 /** 520 Opções de delegação do participante/organizer 521 */ 522 blkAddAtendee.find(".button.participant-delegate").button({ 523 icons: { 524 primary: "ui-icon-transferthick-e-w" 525 }, 526 text: false 527 }).click(function () { 528 if($(this).hasClass('attendee-permissions-change-button')){ 529 if(!$(this).hasClass('disable')){ 530 $(this).removeClass('attendee-permissions-change-button') 531 .find('.ui-icon-transferthick-e-w').removeClass('attendee-permissions-change').end(); 532 blkAddAtendee.find('.block-add-attendee.search').addClass('hidden'); 533 blkAddAtendee.find('.block-add-attendee.search dt').html('Adicionar outros contatos'); 534 } 535 }else{ 536 $(this).addClass('attendee-permissions-change-button') 537 .find('.ui-icon-transferthick-e-w').addClass('attendee-permissions-change').end(); 538 blkAddAtendee.find('.block-add-attendee.search dt').html('Delegar participação para'); 539 blkAddAtendee.find('.block-add-attendee.search').removeClass('hidden'); 540 blkAddAtendee.find('.block-add-attendee.search input.search').focus(); 541 } 542 }) 543 .addClass('tiny'); 544 312 545 //show or hidden permissions attendees 313 546 //blkAddAtendee.find('.block-attendee-list #attendees-users li').click(show_permissions_attendees); … … 481 714 user[0].id = DataLayer.put('participant', {user: user[0].id, isExternal: isExternal}); 482 715 blkAddAtendee.find('dd.attendee-list ul.attendee-list').append( 483 DataLayer.render(path+'templates/participants_add_itemlist.ejs', user)716 DataLayer.render(path+'templates/participants_add_itemlist.ejs', {user:user, acl: objEvent.acl}) 484 717 ) 485 .find('.button.close').addClass('small').button({text:false, icons:{primary:'ui-icon-close'}}).click(function() {486 DataLayer.remove('participant', $(this).parent().find('[type=checkbox]').val());487 $(this).parent().remove();488 }).end()489 718 .scrollTo('max'); 719 callbackAttendee(); 490 720 } 491 721 … … 503 733 504 734 blkAddAtendee.find('dd.attendee-list ul.attendee-list').append( 505 DataLayer.render(path+'templates/participants_add_itemlist.ejs', [{id:newAttendeeId, name: newAttendeeName, mail: newAttendeeEmail, isExternal: 1}]) 506 ).find('.button.close').addClass('small').button({text:false, icons:{primary:'ui-icon-close'}}).click(function() { 507 DataLayer.remove('participant', $(this).parent().find('[type=checkbox]').val()); 508 $(this).parent().remove(); 509 }).end() 510 .scrollTo('max'); 511 735 DataLayer.render(path+'templates/participants_add_itemlist.ejs', [{id:newAttendeeId, name: newAttendeeName, mail: newAttendeeEmail, isExternal: 1, acl: objEvent.acl}]) 736 ).scrollTo('max'); 737 callbackAttendee(); 512 738 513 739 /** … … 573 799 newAttendeeId = DataLayer.put('participant', {user: old_item.find('.id').html(), isExternal: 0}); 574 800 blkAddAtendee.find('dd.attendee-list ul.attendee-list') 575 .append(DataLayer.render(path+'templates/participants_add_itemlist.ejs', [{id: newAttendeeId, name: old_item.find('.name').html(), mail: old_item.find('.mail').html(), isExternal: 0}])) 576 .find('.button').addClass('small').button({text:false, icons: {primary:'ui-icon-close'}}).click(function () { 577 $(this).parent().remove(); 578 }).end() 801 .append(DataLayer.render(path+'templates/participants_add_itemlist.ejs', [{id: newAttendeeId, name: old_item.find('.name').html(), mail: old_item.find('.mail').html(), isExternal: 0, acl: objEvent.acl}])) 579 802 .scrollTo('max'); 580 581 old_item.remove(); 803 /** 804 * Delegação de participação de um participante com permissão apenas de leitura 805 * 806 */ 807 if(!objEvent.acl.organization && !objEvent.acl.write && !objEvent.acl.inviteGuests && objEvent.acl.read ){ 808 809 blkAddAtendee.find('.block-add-attendee.search').addClass('hidden'); 810 blkAddAtendee.find('.block-add-attendee.search dt').html('Adicionar outros contatos'); 811 812 blkAddAtendee.find('.status option').toggleClass('hidden'); 813 blkAddAtendee.find('option[value=5]').attr('selected','selected').trigger('change'); 814 blkAddAtendee.find('.request-update').removeClass('hidden'); 815 816 blkAddAtendee.find('dd.attendee-list ul.attendee-list li .button.close').parents('li').find('input[name="delegatedFrom[]"]').val(blkAddAtendee.find('.me input[name="attendee[]"]').val()); 817 818 blkAddAtendee.find('.me .participant-delegate').addClass('disable ui-button-disabled ui-state-disabled'); 819 blkAddAtendee.find(".button.close").button({ 820 icons: { 821 primary: "ui-icon-close" 822 }, 823 text: false 824 }).click(function () { 825 826 $(this).parents('li').find('input[name="delegatedFrom[]"]').val(''); 827 blkAddAtendee.find('.request-update').addClass('hidden'); 828 blkAddAtendee.find('.status option').toggleClass('hidden'); 829 blkAddAtendee.find('option[value=1]').attr('selected','selected').trigger('change'); 830 blkAddAtendee.find('.me .participant-delegate').removeClass('disable ui-button-disabled ui-state-disabled attendee-permissions-change-button') 831 .find('.ui-icon-person').removeClass('attendee-permissions-change').end(); 832 833 DataLayer.remove('participant', $(this).parents('li').find('[type=checkbox]').val()); 834 $(this).parents('li').remove(); 835 }) 836 .addClass('tiny'); 837 }else{ 838 callbackAttendee(); 839 old_item.remove(); 840 } 582 841 } 583 842 }); … … 586 845 } 587 846 }); 588 589 /* 590 UI.dialogs.addEvent.find('.attendees-list li').hover( 591 function () { 592 $(this).addClass("hover"); 593 }, 594 function () { 595 $(this).removeClass("hover"); 847 //$('.block-add-attendee .search-result-list').selectable(); 848 849 UI.dialogs.addEvent.find('.row.fileupload-buttonbar .button').filter('.delete').button({ 850 icons: { 851 primary: "ui-icon-close" 852 }, 853 text: 'Excluir' 854 }).click(function () { 855 $('.row.fileupload-buttonbar .attachments-list p').remove(); 856 857 var ids = []; 858 $.each($('.attachment-list input'), function (i, input) { ids.push(input.value); }); 859 if(ids.length > 0){ 860 DataLayer.remove('attachment', {filter: ['IN', 'id', ids]}); 861 $('.attachment-list input').remove(); 596 862 } 597 ); 598 */ 599 //$('.block-add-attendee .search-result-list').selectable(); 600 601 UI.dialogs.addEvent.find('.block-attendee-list select.status').change(function(){ 602 if ($(this).val() == 'another') { 603 // jQuery('.block-attendee-list .add-attendee-search').removeClass('hidden'); 604 $(this).qtip({ 605 show: {ready: true}, 606 hide: false, 607 content: { 608 text: $('.block-attendee-list .add-attendee-search').clone().removeClass('hidden'), 609 title: { 610 &n