Changeset 5715


Ignore:
Timestamp:
03/13/12 18:23:02 (11 years ago)
Author:
natan
Message:

Ticket #2434 - Implementacao da repeticao de eventos na agenda e adicao de suporte a relacionamentos 1x1 na API

Location:
trunk
Files:
2 added
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/expressoCalendar/setup/default_records.inc.php

    r5514 r5715  
    2424                //calendar_repeat 
    2525                $oProc->query("ALTER TABLE calendar_repeat ADD CONSTRAINT fk_calendar_repeat_calendar_object FOREIGN KEY (object_id) REFERENCES calendar_object (id) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE;"); 
    26          
     26 
     27                //calendar_repeat_occurrence 
     28                $oProc->query("ALTER TABLE calendar_repeat_occurrence ADD CONSTRAINT fk_calendar_repeat_to_calendar_repeat_occurrence FOREIGN KEY (repeat_id) REFERENCES calendar_repeat (id) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE;");       
     29 
    2730                //calendar_signature 
    2831                $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;"); 
  • trunk/expressoCalendar/setup/setup.inc.php

    r5617 r5715  
    1313        $setup_info['expressoCalendar']['title']        = 'Expresso Calendar'; 
    1414        /* Ao incrementar versão, não esquecer de declarar função do tables_update.inc.php*/ 
    15         $setup_info['expressoCalendar']['version']      = '1.001'; 
     15        $setup_info['expressoCalendar']['version']      = '1.002'; 
    1616        $setup_info['expressoCalendar']['app_order']    = 10; 
    1717         
    18                 $setup_info['expressoCalendar']['tables'][]             =  'attachment'; 
    19                 $setup_info['expressoCalendar']['tables'][]             =  'calendar_attach'; 
    20                 $setup_info['expressoCalendar']['tables'][]             =  'calendar_class';  
    21                 $setup_info['expressoCalendar']['tables'][]             =  'calendar'; 
    22                 $setup_info['expressoCalendar']['tables'][]             =  'calendar_alarm'; 
    23                 $setup_info['expressoCalendar']['tables'][]             =  'calendar_ex_participant';  
    24                 $setup_info['expressoCalendar']['tables'][]             =  'calendar_object';  
    25                 $setup_info['expressoCalendar']['tables'][]             =  'calendar_object_type'; 
    26                 $setup_info['expressoCalendar']['tables'][]             =  'calendar_participant'; 
    27                 $setup_info['expressoCalendar']['tables'][]             =  'calendar_participant_status'; 
    28                 $setup_info['expressoCalendar']['tables'][]             =  'calendar_permission'; 
    29                 $setup_info['expressoCalendar']['tables'][]             =  'calendar_repeat'; 
    30                 $setup_info['expressoCalendar']['tables'][]             =  'calendar_signature'; 
    31         $setup_info['expressoCalendar']['tables'][]             =  'calendar_signature_alarm'; 
    32                 $setup_info['expressoCalendar']['tables'][]             =  'module_preference'; 
    33         $setup_info['expressoCalendar']['tables'][]             =  'calendar_to_calendar_object'; 
    34                                  
     18        $setup_info['expressoCalendar']['tables'][]             =  'attachment'; 
     19        $setup_info['expressoCalendar']['tables'][]             =  'calendar_attach'; 
     20        $setup_info['expressoCalendar']['tables'][]             =  'calendar_class';  
     21        $setup_info['expressoCalendar']['tables'][]             =  'calendar'; 
     22        $setup_info['expressoCalendar']['tables'][]             =  'calendar_alarm'; 
     23        $setup_info['expressoCalendar']['tables'][]             =  'calendar_ex_participant';  
     24        $setup_info['expressoCalendar']['tables'][]             =  'calendar_object';  
     25        $setup_info['expressoCalendar']['tables'][]             =  'calendar_object_type'; 
     26        $setup_info['expressoCalendar']['tables'][]             =  'calendar_participant'; 
     27        $setup_info['expressoCalendar']['tables'][]             =  'calendar_participant_status'; 
     28        $setup_info['expressoCalendar']['tables'][]             =  'calendar_permission'; 
     29        $setup_info['expressoCalendar']['tables'][]             =  'calendar_repeat'; 
     30        $setup_info['expressoCalendar']['tables'][]             =  'calendar_signature'; 
     31        $setup_info['expressoCalendar']['tables'][]             =  'calendar_signature_alarm'; 
     32        $setup_info['expressoCalendar']['tables'][]             =  'module_preference'; 
     33        $setup_info['expressoCalendar']['tables'][]             =  'calendar_to_calendar_object'; 
     34        $setup_info['expressoCalendar']['tables'][]             =  'calendar_repeat_ranges'; 
     35        $setup_info['expressoCalendar']['tables'][]             =  'calendar_repeat_occurrence'; 
     36 
    3537        $setup_info['expressoCalendar']['enable']               = 1; 
    3638 
  • trunk/expressoCalendar/setup/tables_current.inc.php

    r5592 r5715  
    215215                'id' => array( 'type' => 'auto', 'nullable' => False), 
    216216                'frequency' => array(  'type' => 'varchar','precision' => '20', 'nullable' => False), 
    217                 'until' => array(  'type' => 'int', 'precision' => '8', 'nullable' => False), 
     217                'until' => array(  'type' => 'int', 'precision' => '8', 'nullable' => True), 
     218                'dtstart' => array(  'type' => 'bigint','precision' => '16', 'nullable' => True), 
    218219                'count' => array(  'type' => 'int', 'precision' => '8', 'nullable' => True), 
    219220                'object_id' => array(  'type' => 'int', 'precision' => '8', 'nullable' => False), 
     
    236237                ), 
    237238 
     239            'calendar_repeat_ranges' => array( 
     240            'fd' => array( 
     241                'id' => array( 'type' => 'auto', 'nullable' => False), 
     242                'range_start' => array(  'type' => 'bigint','precision' => '16', 'nullable' => False), 
     243                'range_end' => array(  'type' => 'bigint', 'precision' => '16', 'nullable' => False), 
     244                'user_info_id' => array(  'type' => 'bigint', 'precision' => '16', 'nullable' => False) 
     245            ), 
     246            'pk' => array('id'), 
     247            'fk' => array(), 
     248            'ix' => array(), 
     249            'uc' => array() 
     250                ), 
     251 
     252            'calendar_repeat_occurrence' => array( 
     253            'fd' => array( 
     254                'id' => array( 'type' => 'auto', 'nullable' => False), 
     255                'occurrence' => array(  'type' => 'bigint','precision' => '16', 'nullable' => False), 
     256                'repeat_id' => array(  'type' => 'int', 'precision' => '8', 'nullable' => False) 
     257            ), 
     258 
     259            'pk' => array('id'), 
     260            'fk' => array('repeat_id'), 
     261            'ix' => array(), 
     262            'uc' => array() 
     263                ), 
     264 
    238265                'calendar_signature' => array( 
    239266            'fd' => array( 
  • trunk/expressoCalendar/setup/tables_update.inc.php

    r5651 r5715  
    3333        return $GLOBALS['setup_info']['expressoCalendar']['currentver']; 
    3434        } 
     35 
     36        $test[] = '1.001'; 
     37        function expressoCalendar_upgrade1_001() { 
     38 
     39                $oProc = $GLOBALS['phpgw_setup']->oProc; 
     40 
     41                $oProc->query("ALTER TABLE calendar_repeat ADD COLUMN dtstart bigint"); 
     42                $oProc->query('ALTER TABLE calendar_repeat ALTER COLUMN until DROP NOT NULL'); 
     43 
     44                $oProc->CreateTable('calendar_repeat_occurrence', array( 
     45                                'fd' => array( 
     46                                    'id' => array( 'type' => 'auto', 'nullable' => False), 
     47                                    'occurrence' => array(  'type' => 'bigint','precision' => '16', 'nullable' => False), 
     48                                    'repeat_id' => array(  'type' => 'int', 'precision' => '8', 'nullable' => False) 
     49                                ), 
     50 
     51                                'pk' => array('id'), 
     52                                'fk' => array('repeat_id'), 
     53                                'ix' => array(), 
     54                                'uc' => array() 
     55                                ) 
     56                ); 
     57 
     58                $oProc->CreateTable('calendar_repeat_ranges', array( 
     59                                'fd' => array( 
     60                                    'id' => array( 'type' => 'auto', 'nullable' => False), 
     61                                    'range_start' => array(  'type' => 'bigint','precision' => '16', 'nullable' => False), 
     62                                    'range_end' => array(  'type' => 'bigint', 'precision' => '16', 'nullable' => False), 
     63                                    'user_info_id' => array(  'type' => 'bigint', 'precision' => '16', 'nullable' => False) 
     64                                ), 
     65                                'pk' => array('id'), 
     66                                'fk' => array(), 
     67                                'ix' => array(), 
     68                                'uc' => array() 
     69                                    ) 
     70                ); 
     71 
     72                $oProc->query("ALTER TABLE calendar_repeat_occurrence ADD CONSTRAINT fk_calendar_repeat_to_calendar_repeat_occurrence FOREIGN KEY (repeat_id) REFERENCES calendar_repeat (id) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE;");       
     73 
     74                $GLOBALS['setup_info']['expressoCalendar']['currentver'] = '1.002'; 
     75        return $GLOBALS['setup_info']['expressoCalendar']['currentver']; 
     76        } 
    3577?> 
  • trunk/prototype/Sync.php

    r5514 r5715  
    6464                    if( isset( $dt[$linkName] ) ) 
    6565                    { 
    66                             if( $notArray = Controller::isConcept( $concept, $linkName ) ) 
     66                            if( $notArray = Controller::hasOne( $concept, $linkName ) ) 
    6767                                    $dt[$linkName] = array( $dt[$linkName] ); 
    6868 
     
    148148 
    149149                  $return[ $oldURI ] = !$tx['rollback'] ? $dt ?  
    150                                        array( 'id' => $tx['id'] ) : false : 'ROLLBACK';; 
     150                                       array( 'id' => $tx['id'] ) : false : 'ROLLBACK'; 
    151151          } 
    152152    } 
  • trunk/prototype/api/controller.php

    r5637 r5715  
    2727        static $tx = array(); 
    2828        static $isConcept = array(); 
     29        static $hasOne = array(); 
    2930        static $txID = 0; 
    3031        static $wallet; 
     
    161162            $links = array(); 
    162163            self::$isConcept[ $concept ] = array(); 
     164            self::$hasOne[ $concept ] = array(); 
    163165 
    164166            if( isset(self::$config[ $concept ][ 'model.hasOne' ]) ) 
     
    171173 
    172174                    $links[$linkName] = $target; 
    173                     self::$isConcept[ $concept ][ $linkName ] = true; 
     175                    self::$hasOne[ $concept ][ $linkName ] = true; 
    174176                } 
    175177            if( isset(self::$config[ $concept ][ 'model.depends' ]) ) 
     
    182184 
    183185                    $links[$linkName] = $target; 
     186                    self::$hasOne[ $concept ][ $linkName ] = true; 
    184187                    self::$isConcept[ $concept ][ $linkName ] = true; 
    185188                } 
     
    204207 
    205208            return( isset(self::$isConcept[ $concept ][ $linkName ]) ); 
     209        } 
     210 
     211        public static function hasOne( $concept, $linkName ) 
     212        {  
     213            if( !isset( self::$hasOne[ $concept ] ) ) 
     214                self::links( $concept ); 
     215 
     216            return( isset(self::$hasOne[ $concept ][ $linkName ]) ); 
    206217        } 
    207218 
     
    646657 
    647658                foreach( $postpone as $linkTarget => $dt ) 
     659                { 
     660                      if( Controller::hasOne( $URI['concept'], $linkNames[ $linkTarget ] ) ) 
     661                          $dt = array( $dt ); 
     662 
    648663                      foreach( $dt as $ii => $value ) 
    649664                      { 
     
    655670                          self::put( array( 'concept' => $linkTarget ), $value, &$txIds ); 
    656671                      } 
    657  
     672                } 
    658673                if( $commit ) 
    659674                { 
  • trunk/prototype/api/datalayer.js

    r5615 r5715  
    136136    nestedLinks: {}, 
    137137    concepts: {}, 
     138    notArray: {}, 
    138139    listeners: {}, 
    139140    encoders: {}, 
     
    388389                    if( data[i][link] ) 
    389390                    { 
    390                         var isConcept = false; 
    391                        
    392                         if( isConcept = this.isConcept( concept, link ) ) 
     391                        var notArray2 = false; 
     392 
     393                        if( notArray2 = this.hasOne( concept, link ) ) 
    393394                            data[i][link] = [ data[i][link] ]; 
    394395 
    395                         var _this = this; 
     396                        var _this = this, dependency = this.isDependency( concept, link ); 
    396397 
    397398                        $.each( data[i][link], function( ii, el ){ 
     
    404405                                //removido pois o mesmo esta gerando inconsistencia em tudo 
    405406//                              if( DataLayer.isConcept( links[link], nestedLinks[link] ) ) 
    406                                 if( isConcept ) 
     407                                if( !DataLayer.hasOne( links[link], nestedLinks[link] ) ) 
    407408                                { 
    408409                                    el[ nestedLinks[link] ] = el[ nestedLinks[link] ] || []; 
     
    413414 
    414415                                if( isRef && ( !current[ key ] || !current[ key ][ link ] ||  
    415                                                (isConcept ? current[ key ][ link ] !== el.id : !$.inArray( el.id, current[ key ][ link ] )) ) ) 
     416                                               (notArray2 ? current[ key ][ link ] !== el.id : !$.inArray( el.id, current[ key ][ link ] )) ) ) 
    416417                                { 
    417418                                    updateSet[ links[link] ] = updateSet[ links[link] ] || []; 
     
    422423                            }); 
    423424 
    424                         if( isConcept ) 
     425                        if( notArray2 ) 
    425426                            data[i][link] = data[i][link][0]; 
    426427                    } 
     
    489490                    continue; 
    490491 
    491                 if( isConcept = this.isConcept( concept, link ) ) 
     492                if( this.hasOne( concept, link ) ) 
    492493                    current[i][link] = [ current[i][link] ]; 
    493494 
     
    972973 
    973974            this.links[ concept ] =  result['links'] || {}; 
     975             
     976            this.notArray[ concept ] = result['hasOne'] || {}; 
    974977 
    975978           this.nestedLinks[ concept ] = result['nestedLinks'] || {}; 
     
    985988    }, 
    986989     
    987     isConcept: function( concept, attr ){ 
     990    isDependency: function( concept, attr ){ 
    988991       
    989992        if( typeof this.concepts[concept] === "undefined" ) 
     
    993996 
    994997        return !!this.concepts[ concept ][ attr ]; 
     998    }, 
     999     
     1000    hasOne: function( concept, attr ){ 
     1001       
     1002        if( typeof this.notArray[concept] === "undefined" ) 
     1003        { 
     1004            this.links( concept ); 
     1005        } 
     1006 
     1007        return !!this.notArray[ concept ][ attr ]; 
    9951008    }, 
    9961009     
     
    11121125       
    11131126        for( var key in base ) 
    1114             if( this.storage.filter( base[key], this.copy( filter ) ) ) 
     1127            if( this.storage.filter( base[key], filter ) ) 
    11151128                filtered[ filtered.length ] = key; 
    11161129 
     
    11251138 
    11261139     
    1127     compare: function( operator, b, t ){ 
     1140    compare: function( operator, base, test ){ 
    11281141       
    1129         var base = this.converterType(b); 
    1130         var test = this.converterType(t); 
     1142        base = this.converterType(base); 
     1143        test = this.converterType(test); 
    11311144          
    11321145    switch( operator ){ 
     
    11451158        case '<':  return ( base >  test ); 
    11461159         
    1147         default: return false; 
     1160        default: return true; 
    11481161        } 
    11491162       
     
    11641177 
    11651178        if( !filter || !result ) 
    1166           return DataLayer.copy( result || false ); 
    1167  
    1168         var keys = []; 
    1169  
    1170         if( notArray = $.type(filter) === "string" ) 
    1171             keys = [ filter ]; 
    1172         else if( $.type(filter) !== "array" ) 
    1173                 keys = this.filter( result, filter.filter, filter.criteria ); 
     1179          return( result || false ); 
     1180 
     1181        var keys = DataLayer.copy( filter ); 
     1182 
     1183        if( notArray = $.type(keys) === "string" ) 
     1184            keys = [ keys ]; 
     1185        else if( $.type(keys) !== "array" ) 
     1186                keys = this.filter( result, keys.filter, keys.criteria ); 
    11741187 
    11751188        var res = []; 
     
    11781191            res[ res.length ] = result[keys[i]]; 
    11791192 
    1180         return DataLayer.copy( notArray ? res[0] || false : res.length ? res : false ); 
     1193        return( notArray ? res[0] || false : res.length ? res : false ); 
    11811194    }, 
    11821195 
     
    11921205        get: function( key ){ 
    11931206 
    1194             return this.cache[key]; 
     1207            return DataLayer.copy( this.cache[key] ); 
    11951208 
    11961209        }, 
  • trunk/prototype/api/newcontroller.php

    r5437 r5715  
    44    define( 'ROOTPATH', dirname(__FILE__).'/..' ); 
    55 
    6 require_once(ROOTPATH.'/app/config.php'); 
     6require_once(ROOTPATH.'/api/config.php'); 
    77 
    88/** 
     
    2424        static $config = array(); 
    2525        static $includes = array(); 
     26        static $tx = array(); 
     27        static $txID = 0; 
    2628        static $wallet; 
    2729 
     
    4345 
    4446        public static function clearAll() 
    45         { 
     47            { 
    4648            return self::$cache->clearAll(); 
    47         } 
     49            } 
    4850 
    4951        public static function clear( $id ) 
     
    5254        } 
    5355 
    54         public static function get( $id ) 
     56        public static function check( $id ) 
    5557        { 
    5658            return self::$cache->get( $id ); 
    5759        } 
    5860 
    59         public static function put( $id, $data, $expires, $compressed ) 
     61        public static function store( $id, $data, $expires, $compressed ) 
    6062        { 
    6163            return self::$cache->put( $id, $data, $expires, $compressed ); 
    6264        } 
    6365 
    64         public static function find( $concept, $filter, $options = false ) 
    65         { 
    66             if( isset($URI['id']) && $URI['id'] ) 
    67                 return self::read( $URI, $params, $options ); 
    68  
    69             return self::call( 'find', $URI, $params, $options ); 
    70         } 
    71  
    72         public static function read( $concept, $id, $options = false ) 
    73         { 
    74             if( !is_string( $id ) ) 
    75                 return self::find( $concept, $id, $options ); 
    76  
    77             return self::call( 'read', $concept, $id, $options ); 
    78         } 
    7966         
     67 
     68//      public static function read( $concept, $id = false, $options = false ) 
     69//      { 
     70//          if( !isset($URI['id']) || !$URI['id'] ) 
     71//              return self::find( $URI, $params, $criteria ); 
     72//  
     73//          return self::call( 'read', $URI, $params, $criteria ); 
     74//      } 
     75 
    8076//      public static function deleteAll( $URI, $params = false, $criteria = false ) 
    8177//      { 
     
    8682//      } 
    8783 
    88         public static function delete( $concept, $id = false, $options = false ) 
    89         { 
    90 //          if( !isset($URI['id']) || !$URI['id'] ) 
    91 //              return self::deleteAll( $URI, $params, $criteria ); 
    92  
    93             return self::call( 'delete', $URI, $params, $criteria ); 
    94         } 
    95          
    96 //      public static function replace( $URI, $params, $criteria = false ) 
     84        //      public static function replace( $URI, $params, $criteria = false ) 
    9785//      { 
    9886//          if( isset($URI['id']) && $URI['id'] ) 
     
    10290//      } 
    10391 
    104         public static function update( $concept, $params, $filter = false, $options = false ) 
    105         { 
    106             if( !isset($URI['id']) || !$URI['id'] ) 
    107                 return self::replace( $URI, $params, $criteria ); 
    108  
    109             return self::call( 'update', $URI, $params, $criteria ); 
    110         } 
    111  
    112         public static function create( $concept, $params, $filter = false, $options = false ) 
    113         { 
    114             return self::call( 'create', $concept, $params, $filter, $options ); 
    115         } 
    116  
    117         public static function begin( $concept, $id, $options = false ) 
    118         { 
    119             return self::call( 'begin', $concept, $id, $options ); 
    120         } 
    121  
    122         public static function commit( $concept, /*$id,*/ $params = false, $options = false ) 
    123         { 
    124             return self::call( 'commit', $concept, $id, $params, $options ); 
    125         } 
    126  
    127         public static function rollback($concept, /*$id,*/ $options = false ) 
    128         { 
    129             return self::call( 'rollback', $URI, $params, $options ); 
    130         } 
    131  
    132         public static function format( $type, $data, $options = false ) 
    133         { 
    134             return self::call( 'format', $type, $data, $options ); 
    135         } 
    136  
    137         public static function parse( $type, $data, $options = false ) 
    138         { 
    139             return self::call( 'parse', $type, $data, $options ); 
    140         } 
    141  
    142         public static function URI( $className, $id = false, $service = false ) 
    143         { 
    144             return array( 'concept' => $className, 
    145                           'service' => $service ? $service : false,  
    146                           'id' => $id ? $id : '' ); 
    147         } 
    148  
    149         public static function links( $concept ) 
    150         { 
    151             if( !isset(self::$config[ $concept ]) ) 
    152               self::$config[ $concept ] = self::loadConfig( $concept ); 
    153  
    154             return( isset(self::$config[ $concept ]['links']) ?  
    155                           self::$config[ $concept ]['links'] : array() ); 
    156         } 
    157  
    158         public static function isConcept( $concept ) 
    159         { 
    160             if( isset( self::$config[ $concept ] ) &&  
    161                 self::$config[ $concept ] ) 
    162                 return( true ); 
    163             else 
    164                 return file_exists( ROOTPATH."/config/$concept.ini" ); 
    165         } 
    166  
    167         public static function getConcept( $concept ) 
    168         { 
    169             if( isset( self::$config[ $concept ] ) ) 
    170                 return( self::$config[ $concept ] ); 
    171  
    172             return( self::$config[ $concept ] = self::loadConfig( $concept ) ); 
    173         } 
     92        public static function find( $concept, $options ) 
     93        {     
     94            return self::get( $options['filter'],  self::context( $options, array( 'concept' => $concept ) ) ); 
     95        } 
     96 
     97        public static function delete( $concept, $id = false, $options = array() ) 
     98        { 
     99            return self::put( false, self::context( $options, array( 'concept' => $concept, 'id' => $id ) ) ); 
     100        } 
     101 
     102        public static function update( $concept, $data, $id = false, $options = array() ) 
     103        { 
     104            return self::put( $data, self::context( $options, array( 'concept' => $concept, 'id' => $id ) ) ); 
     105        } 
     106 
     107        public static function create( $concept, $data, $options = array() ) 
     108        { 
     109            return self::put( $data, self::context( $options, array( 'concept' => $concept ) ) ); 
     110        } 
     111 
     112        public static function put( $data, $options ) 
     113        { 
     114            try 
     115            { 
     116                $context = self::context( $options ); 
     117 
     118                $txId = self::begin( $context['service'] ); 
     119 
     120                if( $context['format'] ) 
     121                    $data = self::parse( $data, $context['format'], $options ); 
     122 
     123                if( !isset($options['concept']) ) 
     124                { 
     125                    $return = array(); 
     126 
     127                    for( $data as $concept => $dt ) 
     128                         $return[] = self::put( $dt, array_merge( array( 'concept' => $concept ), $options ) ); 
     129                         
     130                    return $return; 
     131                } 
     132 
     133 
     134                $model = self::$models[ $options['concept'] ]; 
     135 
     136                $postpone = array(); 
     137 
     138                if( $data ) 
     139                { 
     140                    foreach( $model['hasMany'] as $linkName => $linkTarget ) 
     141                    { 
     142                        $postpone[$linkTarget] = $dt[$linkName]; 
     143                    } 
     144                    foreach( $model['hasOne'] as $linkName => $linkTarget ) 
     145                    { 
     146                        if( isset( $dt[$linkName] ) && is_array( $dt[$linkName] ) ) 
     147                            $dt[$linkName] = self::put( $dt[$linkName],  array_merge( array( 'concept' => $linkTarget ), $options ) ); 
     148                    } 
     149                } 
     150 
     151                $method =        $dt ? isset( $dt['id'] ) ? 
     152                                'update' : 'create' : 'delete'; 
     153 
     154                $context['id'] = $dt ? isset( $dt['id'] ) ? 
     155                                 $dt['id'] : false : $context['id']; 
     156 
     157                self::before( $concept.':'.$method, &$context, $options ); 
     158                self::call( $method, $options, $dt ); 
     159                self::after( $concept.':'.$method, &$context, $options ); 
     160 
     161                $result = $context['result']; 
     162 
     163                if( !is_bool( $result ) && !is_string( $result ) && isset( $result['id'] ) ) 
     164                      $context['id'] = $result['id']; 
     165 
     166                foreach( $postpone as $linkTarget => $dt ) 
     167                      foreach( $dt as $ii => $value ) 
     168                      { 
     169                          if( !is_array( $value ) ) 
     170                            $value = array( 'id' => $value ); 
     171 
     172                          $value[ $options['concept'] ] = $options['id']; 
     173 
     174                          self::put( $value, array_merge( array( 'concept' => $linkTarget ), $options ) ); 
     175                      } 
     176 
     177                if( $txId ) 
     178                    return self::commit( $options['service'], $txId ); 
     179            } 
     180            catch( Exception $e ) 
     181            { 
     182                if( !self::fallback( $e ) ) 
     183                    self::closeAll(); 
     184 
     185                return( false ); 
     186            } 
     187         
     188            return( $options['id'] ); 
     189        } 
     190 
     191        public static function context( $options, $custom = false ) 
     192        { 
     193            if( $service ) 
     194                $options['service'] = $service; 
     195 
     196            return $options; 
     197        } 
     198 
     199        public static function get( $filter, $options = false ) 
     200        { 
     201            return self::call( 'find', self::context( $options, array( 'filter' => $filter ) ) ); 
     202        } 
     203 
     204        public static function connect( $service, $options ) 
     205        { 
     206            $result = self::call( 'open', self::context( $options, array( 'service' => $service ) ) ); 
     207 
     208            if( is_string( $result ) ) 
     209                throw new Exception( $result ); 
     210 
     211            return( true ); 
     212        } 
     213 
     214        public static function begin( $service, $txId = false, $options = false ) 
     215        { 
     216            $context = self::context( $options ); 
     217 
     218            $result = self::call( 'begin', $options ); 
     219 
     220            if( !$txId ) 
     221                $txId = $result ? $result : self::$txID++; 
     222 
     223            if( isset( self::$transactions[ $txId ] ) ) 
     224                return( false ); 
     225 
     226            self::$transactions[ $txId ] = array( 'txID' => $txId ); 
     227            self::$transactions[ $service ][] =& self::$transactions[ $txId ]; 
     228 
     229            return( $txId ); 
     230        } 
     231 
     232        public static function commit( $service, $txId = false, $options = false ) 
     233        { 
     234            $context = self::context( $options ); 
     235 
     236            $txs = self::$transactions[ $service . ( $txId ? '.'.$txId : '' ) ]; 
     237 
     238            if( !is_array( $txs ) ) $txs = array( $txs ); 
     239 
     240            $return = array(); 
     241 
     242            foreach( $txs as $tx ) 
     243            { 
     244                $txID = $tx['txID']; 
     245 
     246                $result = false; 
     247 
     248                if( !$options || !$options['rollback'] ) 
     249                    $result = self::call( 'commit', $context, $tx ); 
     250 
     251                if( !$result ) 
     252                    $result = self::call( 'rollback', $context, $tx ); 
     253 
     254                $return[ $txID ] = $result; 
     255 
     256                unset( self::$transactions[ $txID ] ); 
     257            } 
     258 
     259            return( $txId ? $return[ $txId ] : $return ); 
     260        } 
     261 
     262        public static function rollback( $service, $txId = false, $options = array() ) 
     263        { 
     264            return self::commit( $service, $txId, self::context( $options, array( 'rollback' => true ) ) ); 
     265        } 
     266 
     267        public static function fallback( $exception, $context ) // ver a melhor forma de tratar exceptions nesse caso 
     268        { 
     269            if( !self::emmit( 'fallback', self::context( $context, array( 'exception' => $exception ) ), $exception ) ) 
     270                error_log( $exception->getMessage() ); 
     271  
     272            return( true ); 
     273        } 
     274 
     275        public static function format( $data, $service = false, $options = array() ) 
     276        { 
     277            return self::call( 'format', self::context( $options, array( 'service' => $service ) ), $data ); 
     278        } 
     279 
     280        public static function parse( $data, $service = false, $options = array() ) 
     281        { 
     282            return self::call( 'parse', self::context( $options, array( 'service' => $service ) ), $data ); 
     283        } 
     284 
     285        public static function before( $eventName, &$context, $extra = false ) 
     286        { 
     287            return self::emmit( 'before.'.$eventName, $context, $extra ); 
     288        } 
     289 
     290        public static function after( $eventName, &$context, $extra = false ) 
     291        { 
     292            return self::emmit( 'after.'.$eventName, $context, $extra ); 
     293        } 
     294 
     295        public static function emmit( $eventName, &$context, $extra = false ) 
     296        { 
     297            if( self::$listeners[ $eventName ] ) 
     298                return( false ); 
     299 
     300            foreach( self::$listeners[ $eventName ] as $listen => $listener ) 
     301            { 
     302                 $return = $listener->$listen( $context, $extra ); 
     303 
     304                 if( $return === false ) 
     305                    return( true ); 
     306 
     307                 $context = self::context( $context, array( 'return' => $return ) ); 
     308            } 
     309 
     310            return( $return ); 
     311        } 
     312 
     313        //TODO: Compatibilizar as configs relativas aos modulos, adicionando os mesmos nas options passadas 
     314        public static function call( $method, $options, $data = false ) //see how data fit in it 
     315        { 
     316            try 
     317            { 
     318                $context = self::context( $options, array( 'data' => $data ) ); 
     319 
     320                $service = $context['service']; 
     321 
     322                if( $context['config'] ) 
     323                    self::connect( $service, $context['config'] ); 
     324 
     325                self::before( $service.'.'.$method, &$context, $options ); 
     326 
     327                if( self::$services[ $service ] ) 
     328                    switch( $method ) 
     329                    {  
     330                        case 'find': $return = self::$services[ $service ]->find( $context['URI'], $context['properties'], $context['criteria'] ); break; 
     331 
     332                        case 'read': $return = self::$services[ $service ]->read( $context['URI'], $context['properties']/*, $criteria*/ ); break; 
     333 
     334                        case 'create': $return = self::$services[ $service ]->create( $context['URI'], $context['properties']/*, $criteria*/ ); break; 
     335 
     336                        case 'delete': $return = self::$services[ $service ]->delete( $context['URI'], $context['properties']/*, $criteria*/ ); break; 
     337 
     338                        case 'deleteAll': $return = self::$services[ $service ]->deleteAll( $context['URI'], $context['properties'], $context['criteria'] ); break; 
     339 
     340                        case 'update': $return = self::$services[ $service ]->update( $context['URI'], $context['properties']/*, $criteria*/ ); break; 
     341 
     342                        case 'replace': $return = self::$services[ $service ]->replace( $context['URI'], $context['properties'], $context['criteria'] ); break; 
     343 
     344                        case 'begin': $return = self::$services[ $service ]->begin( $context['URI'] ); break; 
     345 
     346                        case 'commit': $return = self::$services[ $service ]->commit( $context['URI'], $context['criteria'] ); break; 
     347 
     348                        case 'rollback': $return = self::$services[ $service ]->rollback( $context['URI'], $context['criteria'] ); break; 
     349 
     350                        case 'parse': $return = self::$services[ $service ]->parse( $context['properties'], $context['criteria'] ); break; 
     351 
     352                        case 'analize': $return = self::$services[ $service ]->analize( $context['properties'], $context['criteria'] ); break; 
     353 
     354                        case 'format': $return = self::$services[ $service ]->format( $context['properties'], $context['criteria'] ); break; 
     355 
     356                        default : $return = self::$services[ $service ]->$method( $context['properties'], $context['criteria'] ); 
     357                    } 
     358 
     359                $context['return'] = $return; 
     360 
     361                self::after( $service.'.'.$method, &$context, $options ); 
     362            } 
     363            catch( Exception $e ) 
     364            { 
     365                if( !self::fallback( $e ) ) 
     366                    self::closeAll(); 
     367 
     368                return( false ); 
     369            } 
     370 
     371            return( $context['return'] );  
     372        } 
     373 
     374//      public static function URI( $className, $id = false, $service = false ) 
     375//      { 
     376//          return array( 'concept' => $className, 
     377//                        'service' => $service ? $service : false,  
     378//                        'id' => $id ? $id : '' ); 
     379//      } 
     380 
     381        //TODO: Compatibilizar as configs relativas aos modulos, adicionando os mesmo nos parametros passados 
     382//      public static function links( $concept = false ) 
     383//      { 
     384//          if( !isset(self::$config[ $concept ]) ) 
     385//            self::$config[ $concept ] = self::loadConfig( $concept ); 
     386//  
     387//          return( isset(self::$config[ $concept ]['links']) ?  
     388//                        self::$config[ $concept ]['links'] : array() ); 
     389//      } 
     390 
     391//      public static function isConcept( $concept ) 
     392//      {  
     393//          if( isset( self::$config[ $concept ] ) &&  
     394//              self::$config[ $concept ] ) 
     395//              return( true ); 
     396//              else 
     397//              return file_exists( ROOTPATH."/config/$concept.ini" ); 
     398//      } 
     399 
     400//      public static function getConcept( $concept, $moduleName = false ) 
     401//      { 
     402//          if( isset( self::$config[ $concept ] ) ) 
     403//              return( self::$config[ $concept ] ); 
     404//  
     405//          return( self::$config[ $concept ] = self::loadConfig( $concept, $moduleName ) ); 
     406//      } 
    174407 
    175408        public static function loadCache( $cacheType = 'Memory' ) 
     
    178411            return new MemoryCache(); 
    179412        } 
    180          
    181         public static function loadConfig( $className, $isService = false ) 
     413 
     414        //TODO: Compatibilizar as configs relativas aos modulos, adicionando os mesmo nos parametros passados 
     415        public static function loadConfig( $className, $isService = false) 
    182416        { 
    183417            $fileName = $className.'.'.($isService ? 'srv' : 'ini'); 
    184418 
    185419            $config = self::$cache->get( $fileName ); 
    186  
     420         
    187421            if( !$config ) 
    188422            { 
    189                 $config = parse_ini_file( ROOTPATH."/config/$fileName", true ); 
     423                $config = parse_ini_file( ROOTPATH.'/config/'.$fileName, true ); 
    190424 
    191425                self::$cache->put( $fileName, $config ); 
     
    196430 
    197431        public static function import( $path, $ext = ".php" ) 
    198         { 
    199             
     432        {  
    200433            if( !isset(self::$includes[$path]) ) 
    201             { 
     434        { 
    202435                require_once( ROOTPATH.'/'.$path.$ext ); 
    203436                self::$includes[$path] = false; 
     
    208441 
    209442        public static function load( $path, $class = false ) 
    210         { 
    211              
     443            {  
    212444            if( $return = self::import( $path, "" ) ) 
    213445                return( $return ); 
    214              
     446 
    215447            if( !$class ){ 
    216448                preg_match( '/^\/?.*\/([^\/]+).php$/', $path, $class ); 
     
    236468            { 
    237469                //// Hack //// TODO: passar o init da sessão no login do expresso 
    238                 if ( isset( $_COOKIE[ 'sessionid' ] ) )  
    239                       session_id( $_COOKIE[ 'sessionid' ] );  
    240                  
    241                 @session_start(); 
    242  
    243 //              if( !isset( $_SESSION['wallet'] ) ) 
    244 //              { 
    245 //                  if( isset( $GLOBALS['phpgw_info'] ) ) 
    246 //                  { 
    247 //                              $_SESSION['wallet']['Sieve']['user']          = $GLOBALS['phpgw_info']['user']['account_lid']; 
    248 //                              $_SESSION['wallet']['Sieve']['password']      = $GLOBALS['phpgw_info']['user']['passwd']; 
    249 //  
    250 //                              $_SESSION['wallet']['Cyrus']['user']          = $GLOBALS['phpgw_info']['user']['account_lid']; 
    251 //                              $_SESSION['wallet']['Cyrus']['password']      = $GLOBALS['phpgw_info']['user']['passwd']; 
    252 //  
    253 //                              $_SESSION['wallet']['user']                   = $GLOBALS['phpgw_info']['user']['account_lid']; 
    254 //                      //                      $_SESSION['wallet']['me']['password']      = $_SESSION['phpgw_info']['expressomail']['user']['passwd']; 
    255 //  
    256 //                              $_SESSION['wallet']['PostgreSQL']['user']     = $GLOBALS['phpgw_info']['server']['db_user']; 
    257 //                              $_SESSION['wallet']['PostgreSQL']['password'] = $GLOBALS['phpgw_info']['server']['db_pass']; 
    258 //                              $_SESSION['wallet']['PostgreSQL']['dbname']   = $GLOBALS['phpgw_info']['server']['db_name']; 
    259 //                  } 
    260 //                  else 
    261 //                      $_SESSION['wallet'] = array(); 
    262 //              } 
    263                  
     470                Config::init(); 
     471 
    264472                if(isset($_SESSION['wallet'])) 
    265473                    self::$wallet = $_SESSION['wallet']; 
     
    269477            return isset( self::$wallet[ $serviceName ] )? self::$wallet[ $serviceName ] : false; 
    270478        } 
     479                 
     480         
     481 
     482        public static function configure( $config, $newConfig ) 
     483        { 
     484            foreach( $newConfig as $key => $value ) 
     485                $config[$key] = $value; 
     486 
     487            return( $config ); 
     488            } 
    271489 
    272490        public static function dispatch( $dispatcher, $data, $optionsMap = false ) 
     
    283501        } 
    284502 
    285         public static function loadAll( $configurable, $isService = false ) 
    286         { 
    287         } 
    288  
    289         public static function connect( $service, $config ) 
    290         { 
    291             $result = $service->open( $config ); 
    292  
    293             if( is_string( $result ) ) 
    294                 throw new Exception( $result ); 
    295  
    296             return( true ); 
    297         } 
    298  
    299         public static function open( $serviceName, $config = false ) 
    300         { 
    301             $service = self::$services[ $serviceName ]; 
    302  
    303             $srvConfig = array(); 
     503        //TODO: Compatibilizar as configs relativas aos modulos, adicionando os mesmo nos parametros passados 
     504        public static function service( $serviceName, $concept = false ) 
     505        { 
     506            if( isset( self::$services[ $serviceName ] ) ) 
     507                return self::$services[ $serviceName ]; 
     508 
     509            if( !isset(self::$config[ $serviceName ]) ) 
     510                 self::$config[ $serviceName ] = self::loadConfig( $serviceName, true ); 
     511 
     512            if( !isset(self::$config[ $serviceName ]) ) 
     513                return( false ); 
     514 
     515            if( !isset(self::$config[ $serviceName ]['type']) ) 
     516                self::$config[ $serviceName ]['type'] = 'service'; 
     517 
     518            self::import( 'api/'.self::$config[ $serviceName ]['type'] );   //TODO: Item 4 
     519 
     520            $service = self::load( self::$config[ $serviceName ]['path'], 
     521                                   self::$config[ $serviceName ]['class'] ); 
     522 
     523              $srvConfig = array(); 
    304524 
    305525            if( isset(self::$config[ $serviceName ][ 'config' ]) ) 
     
    307527            if( $wallet = self::wallet( $serviceName ) ) 
    308528                $srvConfig = self::configure( $srvConfig, $wallet ); 
    309             if( $config ) 
    310                 $srvConfig = self::configure( $srvConfig, $config ); 
     529            if( $concept && isset(self::$config[ $concept ]['service.config']) ) 
     530                $srvConfig = self::configure( $srvConfig, self::$config[ $concept ]['service.config'] ); 
    311531 
    312532            if( empty( $srvConfig ) ) 
     
    315535            if( $service && self::$config[ $serviceName ]['type'] === 'service' ) 
    316536                self::connect( $service, $srvConfig ); 
    317         } 
    318  
    319         public static function configure( $config, $newConfig ) 
    320         { 
    321             foreach( $newConfig as $key => $value ) 
    322                 $config[$key] = $value; 
    323  
    324             return( $config ); 
    325         } 
    326  
    327         public static function service( $serviceName, $concept = false ) 
    328         { 
    329             if( isset( self::$services[ $serviceName ] ) ) 
    330                 return self::$services[ $serviceName ]; 
    331  
    332             if( !isset(self::$config[ $serviceName ]) ) 
    333                  self::$config[ $serviceName ] = self::loadConfig( $serviceName, true ); 
    334  
    335             if( !isset(self::$config[ $serviceName ]) ) 
    336                 return( false ); 
    337  
    338             if( !isset(self::$config[ $serviceName ]['type']) ) 
    339                 self::$config[ $serviceName ]['type'] = 'service'; 
    340  
    341             self::import( 'app/'.self::$config[ $serviceName ]['type'] );   //TODO: Item 4 
    342  
    343             self::$services[ $serviceName ] = self::load( self::$config[ $serviceName ]['path'], 
    344                                                           self::$config[ $serviceName ]['class'] ); 
    345  
    346             if( $concept && isset(self::$config[ $concept ]['service.config']) ) 
    347                 self::open( $serviceName, $self::$config[ $concept ]['service.config'] ); 
    348             else 
    349                 self::open( $serviceName ); 
    350537 
    351538            return( self::$services[ $serviceName ] = $service ); 
    352539        } 
    353540 
     541        //TODO: Compatibilizar as configs relativas aos modulos, adicionando os mesmo nos parametros passados 
    354542        public static function interceptor( $method, $concept = false, $serviceName = false, $isService = false ) 
    355543        { 
     
    390578        } 
    391579 
    392         public static function fire( $eventType, $method, $params, $original, $isService = false ) 
    393         { 
    394             $interceptors = self::interceptor( $method, 
    395                                                isset($original['URI']['concept']) ? $original['URI']['concept'] : false, 
    396                                                isset($params['URI']['service']) ? $params['URI']['service'] : false, $isService ); 
    397  
    398             if( $interceptors && isset($interceptors[ $eventType ]) ) 
    399                 foreach( $interceptors[ $eventType ] as $intercept => $interceptor ) 
    400                 { 
    401                     $return = $interceptor->$intercept( $params['URI'], $params['properties'], $params['criteria'], $original, $params['service'] ); 
    402  
    403                     if( $return === false ) 
    404                         return( false ); 
    405  
    406                     if( isset($return) ) 
    407                         $params['properties'] = $return; 
    408                 } 
    409  
    410               return( $params ); 
    411         } 
     580//      public static function interceptorCommit( $eventType, $commitList, $isService = false ) 
     581//      { 
     582//          $result = array( $eventType => array() ); 
     583//          
     584//          if( is_array( $commitList ) ) 
     585//              foreach( $commitList as $i => $tx ) 
     586//              { 
     587//                  $interceptors = self::interceptor( 'commit', $tx['concept'], $tx['service'], $isService ); 
     588//        
     589//                  $result[$eventType] = array_merge( $result[$eventType], $interceptors[$eventType] ); 
     590//              } 
     591//  
     592//          return( $result ); 
     593//      } 
     594 
     595//      public static function fire( $eventType, $method, &$params, $original, $isService = false ) 
     596//      { 
     597//          if( $method === 'commit' ) 
     598//              $interceptors = self::interceptorCommit( $eventType, $params['criteria'], $isService ); 
     599//  
     600//          else 
     601//              $interceptors = self::interceptor( $method, 
     602//                                                 isset($original['URI']['concept']) ? $original['URI']['concept'] : false, 
     603//                                                 isset($params['URI']['service']) ? $params['URI']['service'] : false, $isService ); 
     604//  
     605//          if( $interceptors && isset($interceptors[ $eventType ]) ) 
     606//              foreach( $interceptors[ $eventType ] as $intercept => $interceptor ) 
     607//              { 
     608//                  $return = $interceptor->$intercept( $params['URI'], $params['properties'], $params['criteria'], $original/*, $params['service']*/ ); 
     609//  
     610//                  if( $return === false ) 
     611//              return( false ); 
     612//  
     613//                  if( isset($return) ) 
     614//                      $params['properties'] = $return; 
     615//              } 
     616//  
     617//            return( $params ); 
     618//      } 
    412619 
    413620        /* 
     
    424631        */ 
    425632 
    426         public static function call( $method, $URI, $properties, $criteria = false, $service = false ) 
    427         { 
    428             try 
    429             { 
    430                 $original = $params = array( 'properties' => $properties,  
    431                                              'criteria' => $criteria,  
    432                                              'URI' => $URI, 
    433                                              'service' => $service ); 
    434  
    435                 if( isset($params['URI']['concept']) ) 
    436                     $params = self::fire( 'before', $method, $params, $original ); 
    437  
    438                 if( !$params['service'] ) 
    439                 { 
    440                     $isInternal = true; 
    441  
    442                     if( ( !isset($params['URI']['service']) || !$params['URI']['service'] ) && isset($params['URI']['concept']) ) 
    443                     { 
    444                         if( !isset(self::$config[ $URI['concept'] ]) ) 
    445                             self::$config[ $URI['concept'] ] = self::loadConfig( $URI['concept'] ); 
    446  
    447                         $params['URI']['service'] = self::$config[ $URI['concept'] ][ 'service' ]; 
    448                     } 
    449  
    450                     if( !isset($params['URI']['service']) ) 
    451                         return( false ); 
    452  
    453                     $params['service'] = self::service( $params['URI']['service'], isset($params['URI']['concept']) ? $params['URI']['concept'] : false ); 
    454                 } 
    455  
    456                 if( isset($params['URI']['service']) ) 
    457                     $params = self::fire( 'before', $method, $params, $original, true ); 
    458  
    459                 if( $params['service'] ) 
    460                     switch( $method ) 
    461                     { 
    462                         case 'find': $return = $params['service']->find( $params['URI'], $params['properties'], $params['criteria'] ); break; 
    463  
    464                         case 'read': $return = $params['service']->read( $params['URI'], $params['properties']/*, $criteria*/ ); break; 
    465  
    466                         case 'create': $return = $params['service']->create( $params['URI'], $params['properties']/*, $criteria*/ ); break; 
    467  
    468                         case 'delete': $return = $params['service']->delete( $params['URI'], $params['properties']/*, $criteria*/ ); break; 
    469  
    470                         case 'deleteAll': $return = $params['service']->deleteAll( $params['URI'], $params['properties'], $params['criteria'] ); break; 
    471  
    472                         case 'update': $return = $params['service']->update( $params['URI'], $params['properties']/*, $criteria*/ ); break; 
    473  
    474                         case 'replace': $return = $params['service']->replace( $params['URI'], $params['properties'], $params['criteria'] ); break; 
    475  
    476                         case 'begin': $return = $params['service']->begin( $params['URI'] ); break; 
    477  
    478                         case 'commit': $return = $params['service']->commit( $params['URI'] ); break; 
    479  
    480                         case 'rollback': $return = $params['service']->rollback( $params['URI'] ); break; 
    481  
    482                         case 'parse': $return = $params['service']->parse( $params['properties'], $params['criteria'] ); break; 
    483  
    484                         case 'format': $return = $params['service']->format( $params['properties'], $params['criteria'] ); break; 
    485                     } 
    486      
    487                 if( isset($return) && $return !== false ) 
    488                     $params['properties'] = $return; 
    489  
    490                 if( isset($params['URI']['service']) ) 
    491                     $params = self::fire( 'after', $method, $params, $original, true ); 
    492  
    493                 if( isset($URI['concept']) ) 
    494                     $params = self::fire( 'after', $method, $params, $original ); 
    495             } 
    496             catch( Exception $e ) 
    497             { 
    498                 if( !self::fallback( $e ) ) 
    499                     self::closeAll(); 
    500  
    501                 return( false ); 
    502             } 
    503  
    504             return( empty($params['properties']) ? false : $params['properties'] ); 
    505         } 
    506  
    507         public static function fallback( $exception ) 
    508         { 
    509             error_log( $exception->getMessage() ); 
    510             return( true ); 
     633        //TODO: Compatibilizar as configs relativas aos modulos, adicionando os mesmo nos parametros passados 
     634        public static function serviceName( $URI, $original = false ) 
     635        { 
     636             $concept = ""; 
     637 
     638            if( $original && isset($original['concept']) && $original['concept'] ) 
     639                $concept = $original['concept']; 
     640            elseif( isset($URI['concept']) && $URI['concept'] ) 
     641                $concept = $URI['concept']; 
     642 
     643            if( ( !isset($URI['service']) || !$URI['service'] ) && $concept ) 
     644            { 
     645                if( !isset(self::$config[ $concept ]) ) 
     646                    self::$config[ $concept ] = self::loadConfig( $concept ); 
     647 
     648                $URI['service'] = self::$config[ $concept ][ 'service' ]; 
     649            } 
     650 
     651            if( !isset($URI['service']) ) 
     652                throw new Exception( "CONFIGURATION ERROR: service name from concept '$concept' not found" ); 
     653 
     654            return( $URI ); 
    511655        } 
    512656} 
  • trunk/prototype/config/attachment.ini

    r5592 r5715  
    11service = PostgreSQL 
    22PostgreSQL.concept = attachment 
    3  
    4 [model.hasOne] 
    5 schedulable = schedulable.attachments 
    63 
    74[before.create] 
  • trunk/prototype/config/repeat.ini

    r5514 r5715  
    11service = PostgreSQL 
     2PostgreSQL.concept = calendar_repeat 
    23 
    34[model.depends] 
    45schedulable = schedulable.repeat 
    56 
     7; [model.hasMany] 
     8; occurrences = repeatOccurrence.repeat 
     9 
     10[before.create] 
     11prepareRepeat = modules/calendar/interceptors/DBMapping.php 
     12;  
     13[before.update] 
     14prepareRepeat = modules/calendar/interceptors/DBMapping.php 
     15 
     16[after.create] 
     17saveOccurrences = modules/calendar/interceptors/DBMapping.php 
     18 
     19[after.update] 
     20saveOccurrences = modules/calendar/interceptors/DBMapping.php 
     21 
     22[after.find] 
     23deepnessRepeat = modules/calendar/interceptors/DBMapping.php 
     24;reprepareRepeat = modules/calendar/interceptors/DBMapping.php 
     25 
     26[after.read] 
     27deepnessRepeat = modules/calendar/interceptors/DBMapping.php 
     28;reprepareRepeat = modules/calendar/interceptors/DBMapping.php 
     29 
     30[PostgreSQL.mapping] 
     31wkst = wkst 
     32byweekno = byweekno 
     33byminute = byminute 
     34bysecond = bysecond 
     35byyearday = byyearday 
     36bymonthday = bymonthday 
     37bysetpos = bysetpos 
     38byday = byday 
     39byhour = byhour 
     40interval = interval 
     41frequency = frequency 
     42endTime = until 
     43schedulable = object_id 
     44id = id 
     45count = count 
     46startTime = dtstart 
  • trunk/prototype/config/schedulable.ini

    r5514 r5715  
    4848transparent = transp 
    4949class = class_id 
    50 repeat = repeat 
     50;repeat = repeat 
    5151rangeStart = range_start 
    5252rangeEnd = range_end 
  • trunk/prototype/config/schedulableToAttachment.ini

    r5514 r5715  
    22PostgreSQL.concept = calendar_attach 
    33 
    4 [model.hasOne] 
     4[model.depends] 
    55schedulable = schedulable.attachments 
    66 
  • trunk/prototype/links.php

    r5514 r5715  
    1616    $concepts = array(); 
    1717    $nestedLinks = array(); 
     18    $hasOne = array(); 
    1819 
    1920    foreach( $link as $linkName => $linkTarget ) 
     
    2223            $concepts[ $linkName ] = true; 
    2324 
     25         if( Controller::hasOne( $concept, $linkName ) ) 
     26            $hasOne[ $linkName ] = true; 
     27 
    2428          $nestedLinks[ $linkName ] = Controller::links( $concept, $linkName ); 
    2529    } 
    2630 
    27     $return[ $target ] = array( 'concepts' => $concepts, 'links' => $link, 'nestedLinks' => $nestedLinks ); 
     31    $return[ $target ] = array( 'concepts' => $concepts, 'links' => $link, 'nestedLinks' => $nestedLinks, 'hasOne' => $hasOne ); 
    2832} 
    2933 
  • trunk/prototype/modules/calendar/export.php

    r5514 r5715  
    5454                $event['attachments'] = Controller::find( array( 'concept' => 'attachment' ) , false ,array( 'filter' => array('IN', 'id' , $attachments) ));  
    5555        } 
    56                  
     56         
     57    $repeat = Controller::find( array( 'concept' => 'repeat' ) , false ,array( 'filter' => array('=', 'schedulable'  ,  $event['id']) ));     
     58         
     59    if(is_array($repeat)) 
     60        $event['repeat'] = $repeat[0]; 
     61 
     62      
    5763    $ics = Controller::format( array( 'service' => 'iCal' ) , array($event) , array('defaultTZI' => $event['timezone']) ); 
    5864     
  • trunk/prototype/modules/calendar/interceptors/DBMapping.php

    r5682 r5715  
    77class DBMapping extends Helpers {        
    88            
    9     public function encodeCreateSchedulable( &$uri , &$params , &$criteria , $original ){                        
    10         $params['type_id'] = EVENT_ID; 
    11          
    12          
    13                 if(!is_numeric($params['startTime']) ) 
    14                         $params['startTime'] =  strtotime( $params['startTime'] . ' ' .$params['timezone']).'000'; 
     9    public function encodeCreateSchedulable( &$uri , &$params , &$criteria , $original ){ 
     10        $params['type_id'] = EVENT_ID; 
     11 
     12        if(!is_numeric($params['startTime']) ) 
     13          $params['startTime'] =   self::parseTimeDate( $params['startTime'], $params['timezone'] );  
    1514                 
    16                 if (!is_numeric($params['endTime'])){ 
    17                         $params['endTime'] =   strtotime( $params['endTime'] . ' ' .$params['timezone']).'000'; 
    18                          
    19                         if($params['allDay']) 
    20                                 $params['endTime'] =  $params['endTime']  + 86400000; 
    21                 } 
     15        if (!is_numeric($params['endTime'])){ 
     16          $params['endTime'] =    self::parseTimeDate( $params['endTime'], $params['timezone'] );  
     17 
     18          if($params['allDay']) 
     19            $params['endTime'] =  $params['endTime']  + 86400000; 
     20        } 
    2221    //        if( !isset( $new['repeat'] )) 
    2322    //            $new['range_end'] = '7287926400'; // 12/12/2200 
    2423    //        else 
    2524            $params['rangeEnd'] = $params['endTime']; 
    26                         $params['rangeStart'] =  $params['startTime']; 
     25            $params['rangeStart'] =  $params['startTime']; 
    2726 
    2827            /////////////////////////////////////////////////////////////////// 
     
    3231            $params['type'] = EVENT_ID; 
    3332            $params['uid'] = isset($params['uid']) ? $params['uid'] : $this->_makeUid(); 
    34              
    35         }        
     33    } 
     34 
     35    static function parseTimeDate($time, $timezone){ 
     36        return strtotime( $time . ' ' .$timezone).'000';          
     37   }     
    3638                 
    3739    public function encodeCreateAlarm( &$uri , &$params , &$criteria , $original ){ 
     
    8991           if(isset($params['isExternal']) && $params['isExternal'] == '1') 
    9092                $uri['service'] = 'PostgreSQL';  
    91     }   
     93    } 
     94 
     95    public function prepareRepeat(&$uri , &$params , &$criteria , $original ){ 
     96 
     97          $timezone = Controller::read( array( 'concept' => 'schedulable', 'id' => $params['schedulable'] ), array('timezone') ); 
     98          $params['startTime'] = self::parseTimeDate( $params['startTime'], $timezone['timezone'] ); 
     99          $params['endTime'] = self::parseTimeDate( $params['endTime'], $timezone['timezone'] ); 
     100    } 
    92101       
    93    public function findSchedulable( &$uri , &$params , &$criteria , $original ) 
     102    public function findSchedulable( &$uri , &$params , &$criteria , $original ) 
    94103   { 
    95104       if(isset($criteria['filter'][3][1]) && $criteria['filter'][3][1] == 'calendar') 
    96105       { 
    97          $select = 'calendar_object.id as id ,calendar_object.cal_uid as "uid" , calendar_object.type_id as "type", calendar_object.dtstart as "startTime", calendar_object.summary as "summary", calendar_object.description as "description", calendar_object.dtend as "endTime" , calendar_object.location as "location", calendar_object.allday as "allDay", calendar_object.transp as "transparent", calendar_object.class_id as "class", calendar_object.repeat as "repeat", calendar_object.range_start as "rangeStart",calendar_object.range_end as "rangeEnd", calendar_object.last_update as "lastUpdate", calendar_object.dtstamp as "dtstamp", calendar_object.sequence as "sequence",  calendar_object.tzid as "timezone" ,calendar_to_calendar_object.calendar_id as calendar'; 
    98          $sql = " SELECT $select FROM calendar_to_calendar_object , calendar_object WHERE (range_start >= '".$criteria['filter'][1][2]."' AND range_end <= '".$criteria['filter'][2][2]."' AND calendar_to_calendar_object.calendar_id IN ('".  implode('\',\'', $criteria['filter'][3][2])."')) AND calendar_to_calendar_object.calendar_object_id = calendar_object.id"; 
    99          $params = Controller::service('PostgreSQL')->execResultSql($sql); 
     106          $start = $criteria['filter'][1][2]; 
     107          $end = $criteria['filter'][2][2]; 
     108 
     109         $sql = ' SELECT calendar_object.id as id ,calendar_object.cal_uid as "uid", calendar_object.type_id as "type", calendar_object.dtstart as "startTime", calendar_object.summary as "summary", calendar_object.description as "description", calendar_object.dtend as "endTime" , calendar_object.location as "location", calendar_object.allday as "allDay", calendar_object.transp as "transparent", calendar_object.class_id as "class", calendar_object.repeat as "repeat", calendar_object.range_start as "rangeStart",calendar_object.range_end as "rangeEnd", calendar_object.last_update as "lastUpdate", calendar_object.dtstamp as "dtstamp", calendar_object.sequence as "sequence",  calendar_object.tzid as "timezone" ,calendar_to_calendar_object.calendar_id as calendar FROM calendar_to_calendar_object , calendar_object WHERE (range_start >= \''.$start.'\' AND range_end <= \''.$end.'\' AND calendar_to_calendar_object.calendar_id IN (\''.  implode('\',\'', $criteria['filter'][3][2]).'\')) AND calendar_to_calendar_object.calendar_object_id = calendar_object.id'; 
     110          
     111         $params = Controller::service('PostgreSQL')->execResultSql($sql); 
    100112         $params = self::deepnessFindEvent( &$uri , &$params , &$criteria , $original); 
     113 
     114         $occ = self::checkOccurrences( $criteria['filter'][1][2], $criteria['filter'][2][2], intval($criteria['deepness']) + 1 ); 
     115 
     116         if( $occ ) 
     117            $params = array_merge( $params, $occ ); 
     118 
    101119         return false; 
    102120       } 
    103121   } 
     122 
     123  public function deepnessFindRepeatOccurrence( &$uri , &$result , &$criteria , $original ) 
     124  { 
     125 
     126    if( !isset($criteria['deepness']) || $criteria['deepness'] == 0 ) 
     127          return; 
     128 
     129      foreach( $result as $i => &$res ) 
     130          if( isset($res['repeat']) ) 
     131              $res['repeat'] = Controller::read( array( 'concept' => 'repeat', 'id' => $res['repeat'] ), false, array( 'deepness' => intval( $criteria['deepness'] ) - 1 ) ); 
     132  } 
     133 
     134  public function deepnessRepeat( &$uri , &$result , &$criteria , $original ) 
     135  { 
     136 
     137      if( !isset($criteria['deepness']) || $criteria['deepness'] == 0 ) 
     138          return; 
     139 
     140        $result['schedulable'] = Controller::find( array( 'concept' => 'schedulable' ), false, array( 'filter' => array( '=', 'id', $result['schedulable'] ), 'deepness' => intval( $criteria['deepness'] ) - 1 ) ); 
     141        $result['schedulable'] = $result['schedulable'][0]; 
     142  } 
     143 
     144public function saveOccurrences( &$uri , &$result , &$criteria , $original ){ 
     145 
     146        $ranges = Controller::find( array( 'concept' => 'repeatRange' ), array( 'rangeStart', 'rangeEnd' ),  array( 'filter' => array( '=', 'user', Config::me("uidNumber") ) ) ); 
     147 
     148        if( !is_array( $ranges ) || !isset( $ranges[0]['rangeStart'] ) || !isset( $ranges[0]['rangeEnd'] ) ) 
     149            return; 
     150 
     151        if( isset( $result['id'] ) ) 
     152             $id = $result['id']; 
     153        else 
     154             $id = $uri['id'];  
     155 
     156        $repeat = Controller::read( array( 'concept' => 'repeat', 'id' => $id ) ); 
     157 
     158        unset( $repeat['schedulable'] ); 
     159        unset( $repeat['id'] ); 
     160 
     161        $params = self::decodeRepeat( $repeat, $ranges[0]['rangeStart'], $ranges[0]['rangeEnd'] ); 
     162 
     163        Controller::delete( array( 'concept' => 'repeatOccurrence' ), false, array( 'filter' => array( '=', 'repeat', $id ) ) ); 
     164 
     165        if( !empty($params) ) 
     166            Controller::service('PostgreSQL')->execResultSql( "INSERT INTO calendar_repeat_occurrence(repeat_id,occurrence)VALUES('".$id."', '".implode( "'),('".$id."','", $params )."')" ); 
     167 
     168    } 
     169 
     170    public function checkOccurrences( $start, $end, $deep ){ 
     171 
     172        $ranges = Controller::find( array( 'concept' => 'repeatRange' ), array( 'rangeStart', 'rangeEnd' ),  array( 'filter' => array( '=', 'user', Config::me("uidNumber") ) ) ); 
     173        $ranges = $ranges[0]; 
     174 
     175        $origStart = $start; 
     176        $origEnd = $end; 
     177 
     178        if( $initialized = (isset($ranges['rangeStart']) && isset($ranges['rangeEnd'])) ) 
     179        { 
     180            if( $ranges['rangeStart'] <= $start ) 
     181                $start = false; 
     182            if( $ranges['rangeEnd'] >= $end ) 
     183                $end = false; 
     184        } 
     185 
     186        $repeats = self::findRepeats(); 
     187 
     188        if( !is_array( $repeats ) || empty( $repeats ) ) 
     189            return( false ); 
     190 
     191        $result = array(); 
     192        $ids = array(); 
     193 
     194        foreach( $repeats as $repeat ) 
     195        { 
     196            $ids[] = $id = $repeat['id']; unset( $repeat['id'] );  
     197 
     198            if( !isset( $result[ $id ] ) ) 
     199                $result[ $id ] = array(); 
     200 
     201            if( !$initialized ) 
     202                $result[ $id ] = array_merge( $result[ $id ], self::decodeRepeat( $repeat, $start, $end ) ); 
     203            else 
     204            { 
     205                if( $start ) 
     206                    $result[ $id ] = array_merge( $result[ $id ], self::decodeRepeat( $repeat, $start, $ranges['rangeStart'] ) ); 
     207 
     208                if( $end ) 
     209                    $result[ $id ] = array_merge( $result[ $id ], self::decodeRepeat( $repeat, $ranges['rangeEnd'], $end ) ); 
     210            } 
     211 
     212            if( empty( $result[ $id ] ) ) 
     213                unset( $result[ $id ] ); 
     214        } 
     215 
     216        if( $start || $end ) 
     217        { 
     218            Controller::begin( array( 'service' => 'PostgreSQL') ); 
     219 
     220            foreach( $result as $id => $res ) 
     221                Controller::service('PostgreSQL')->execResultSql( "INSERT INTO calendar_repeat_occurrence(repeat_id,occurrence)VALUES('".$id."','".implode( "'),('".$id."', '", $res )."')" ); 
     222 
     223            $data = array(); 
     224 
     225            if( $start ) 
     226                $data['rangeStart'] = $start; 
     227 
     228            if( $end ) 
     229                $data['rangeEnd'] = $end; 
     230 
     231            if( !$initialized ) 
     232                $data['user'] = Config::me( 'uidNumber' ); 
     233 
     234            Controller::call( ( $initialized ? 'replace' : 'create' ), array( 'concept' => 'repeatRange' ), $data, array( 'filter' => array( '=', 'user', Config::me('uidNumber') ) ) ); 
     235 
     236            Controller::commit( array( 'service' => 'PostgreSQL' ) ); 
     237        } 
     238 
     239        $return = Controller::find( array( 'concept' => 'repeatOccurrence' ), false, array( 'filter' => array( 'AND', array( '>=', 'occurrence', $origStart ), array( '<=', 'occurrence', $origEnd ), array( 'IN', 'repeat', $ids ) ), 'deepness' => $deep ) ); 
     240 
     241        if( !is_array( $return ) ) 
     242          return( false ); 
     243 
     244        $result = array(); 
     245        $params = array(); 
     246 
     247        foreach( $return as $ret ) 
     248        { 
     249              $currentId = $ret['repeat']['schedulable']['id']; 
     250 
     251              if( !isset( $result[ $currentId ] ) ) 
     252              { 
     253                    $result[ $currentId ] = $ret['repeat']['schedulable']; 
     254                    $result[ $currentId ][ 'occurrences' ] = array(); 
     255   
     256                    $calendarToCalendarObj = self::schedulable2calendarToObject( $currentId ); 
     257 
     258                    $result[ $currentId ]['calendar'] = $calendarToCalendarObj[0]['calendar_id']; 
     259 
     260                    unset( $result[ $currentId ]['repeat'] ); 
     261              } 
     262       
     263              $result[ $currentId  ][ 'occurrences' ][] = $ret['occurrence']; 
     264 
     265        } 
     266 
     267        foreach( $result as $id => $res ) 
     268            $params[] = $res; 
     269 
     270        return( $params ); 
     271    } 
     272 
     273    public static function findRepeats() 
     274    { 
     275        return Controller::service('PostgreSQL')->execResultSql( 'SELECT calendar_repeat.wkst as "wkst", calendar_repeat.byweekno as "byweekno", calendar_repeat.byminute as "byminute", calendar_repeat.bysecond as "bysecond", calendar_repeat.byyearday as "byyearday", calendar_repeat.bymonthday as "bymonthday", calendar_repeat.bysetpos as "bysetpos", calendar_repeat.byday as "byday", calendar_repeat.byhour as "byhour", calendar_repeat.interval as "interval", calendar_repeat.frequency as "frequency", calendar_repeat.until as "endTime", calendar_repeat.id as "id", calendar_repeat.count as "count", calendar_repeat.dtstart as "startTime" FROM calendar_repeat, calendar_participant WHERE calendar_repeat.object_id = calendar_participant.object_id AND calendar_participant.user_info_id = \''.Config::me('uidNumber').'\'' ); 
     276    } 
     277         
     278//HELPERS 
     279    public static function decodeRepeat( $repeat , $start , $end ) { 
     280 
     281    date_default_timezone_set( 'UTC' ); 
     282 
     283    require_once ROOTPATH.'/plugins/when/When.php'; 
     284 
     285    $r = new When(); 
     286 
     287    if( $repeat['frequency'] === 'none' ) 
     288        return( array() ); 
     289 
     290    $start =  new DateTime( '@'.(int)( max( $start, $repeat['startTime']  ) / 1000 ), new DateTimeZone('UTC') );     
     291 
     292    foreach($repeat as $rule => $value) 
     293    { 
     294            if( !isset( $value ) || !$value || $value === "0" ) 
     295                continue; 
     296 
     297            switch(strtolower($rule)) 
     298            { 
     299                    case "starttime": break; 
     300                    case "frequency": 
     301                            $r->recur( $start, $value ); 
     302                            break; 
     303                    case "endtime": 
     304                            $r->until( new DateTime( '@'.(int)( $value / 1000 ) ) ); 
     305                            break; 
     306                    case "count": case "interval":  case "wkst": 
     307                            $r->$rule( $value ); 
     308                            break; 
     309                    default : 
     310                            $r->$rule( !is_array( $value ) ? explode( ',' , $value ) : $value ); 
     311                            break; 
     312            } 
     313    } 
     314 
     315    $return = array(); 
     316 
     317    while($result = $r->next()) 
     318    {  
     319       $u = $result->format('U') * 1000; 
     320 
     321       if( $u  > $end ) //data da repetição atual maior que a data final da busca do usuario ? 
     322           break; 
     323 
     324      $return[] = $u; 
     325    } 
     326 
     327    return( $return ); 
     328} 
    104329    
    105330/////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     
    200425      
    201426         public function deepnessFindCalendarShared( &$uri , &$result , &$criteria , $original ){                                
    202                 if(isset($original['criteria']['deepness']) && count($result) > 0){ 
     427                if(isset($original['criteria']['deepness']) && $original['criteria']['deepness'] != '0' && count($result) > 0){ 
    203428                        $calendarIds = array(); 
    204429                        foreach($result as $key => $value) 
     
    234459    public function deepnessFindEvent( &$uri , &$result , &$criteria , $original ){              
    235460 
    236        if(isset($original['criteria']['deepness'])) 
     461       if(isset($original['criteria']['deepness']) && $original['criteria']['deepness'] != 0) 
    237462       { 
    238463                         
     
    286511                                         
    287512                                         
    288                                          
    289                                         $attachmentRelation = Controller::find( array( 'concept' => 'schedulableToAttachment' ) , false ,array( 'filter' => array('=', 'schedulable'  ,  $v['id']) ));  
    290                                         if(is_array($attachmentRelation)){ 
    291                                                 $attachments = array(); 
    292                                                 foreach($attachmentRelation as $key => $value) 
    293                                                         if(isset($value['attachment']) || !!$value['attachment']) 
    294                                                                 $attachments[$key]  = $value['attachment']; 
    295                                                 //Pega os anexos sem source 
    296                                                 $result[$i]['attachments'] = Controller::find( array( 'concept' => 'attachment' ) , array('id', 'name', 'type', 'size') ,array( 'filter' => array('IN', 'id' , $attachments) ));  
    297                                         } 
    298                                  
    299                                 }                
     513                     
     514                    $attachmentRelation = Controller::find( array( 'concept' => 'schedulableToAttachment' ) , false ,array( 'filter' => array('=', 'schedulable'  ,  $v['id']) ));  
     515                    if(is_array($attachmentRelation)){ 
     516                            $attachments = array(); 
     517                            foreach($attachmentRelation as $key => $value) 
     518                                    if(isset($value['attachment']) || !!$value['attachment']) 
     519                                            $attachments[$key]  = $value['attachment']; 
     520                            //Pega os anexos sem source 
     521                            $result[$i]['attachments'] = Controller::find( array( 'concept' => 'attachment' ) , array('id', 'name', 'type', 'size') ,array( 'filter' => array('IN', 'id' , $attachments) ));  
     522                    } 
     523 
     524                    if(isset($result[$i]['repeat'])){ 
     525                      $repeat = Controller::read( array( 'concept' => 'repeat', 'id' => $result[$i]['repeat'] ) ); 
     526 
     527                      if( !is_array($repeat) ) 
     528                          unset( $result[$i]['repeat'] ); 
     529                      else 
     530                          $result[$i]['repeat'] = $repeat[0]; 
     531                    } 
     532            }                
    300533                 
    301534           } 
     
    309542    public function deepnessReadEvent( &$uri , &$result , &$criteria , $original ){              
    310543        
    311        if(isset($original['criteria']['deepness'])) 
     544       if(isset($original['criteria']['deepness']) && $original['criteria']['deepness'] != 0) 
    312545       { 
    313546            if(isset($result['id'])) 
     
    334567    public function deepnessReadParticipant( &$uri , &$result , &$criteria , $original ){                
    335568        
    336        if(isset($original['criteria']['deepness'])) 
     569       if(isset($original['criteria']['deepness']) && $original['criteria']['deepness'] != 0) 
    337570       { 
    338571            if(isset($result['id'])) 
     
    350583    public function deepnessFindParticipant( &$uri , &$result , &$criteria , $original ){                
    351584        
    352        if(isset($original['criteria']['deepness'])) 
     585       if(isset($original['criteria']['deepness']) && $original['criteria']['deepness'] != 0) 
    353586       { 
    354587           foreach ($result as $i => $v) 
     
    369602    public function deepnessReadCalendarSignature( &$uri , &$result , &$criteria , $original ){          
    370603        
    371        if(isset($original['criteria']['deepness'])) 
     604       if(isset($original['criteria']['deepness']) && $original['criteria']['deepness'] != 0) 
    372605            if(isset($result['calendar'])){ 
    373606                $result['calendar'] = Controller::read( array( 'concept' => 'calendar' , 'id' => $result['calendar']));  
     
    380613    public function deepnessFindCalendarSignature( &$uri , &$result , &$criteria , $original ){          
    381614 
    382         if(isset($original['criteria']['deepness'])) 
     615        if(isset($original['criteria']['deepness']) && $original['criteria']['deepness'] != 0) 
    383616       { 
    384617           foreach ($result as $i => $v) 
     
    387620                    $result[$i]['calendar'] = Controller::read( array( 'concept' => 'calendar' , 'id' => $v['calendar']), false, false);  
    388621                                        $result[$i]['defaultAlarms'] = Controller::find( array( 'concept' => 'calendarSignatureAlarm' ) , false ,array( 'filter' => array('=', 'calendarSignature'  ,  $v['id']) ));     
    389                                         //Caso não seja o dono da agenda retorna o objeto permission com as acls 
     622                                        //Caso não seja o dono da agenda retorna o objeto permission com as acls 
    390623                                        if($result[$i]['isOwner'] == 0){ 
    391624                                                $permission = Controller::find( array( 'concept' => 'calendarToPermission'), false ,array( 'filter' => array('AND', array('=', 'calendar' ,  $v['calendar']), array('=', 'user', Config::me('uidNumber') ) ) ) );  
     
    504737                     ))); 
    505738             
    506             return false; /* Mata o restante da execução */ 
     739            return false; /* Mata o restante da execução */ 
    507740        }  
    508741         
     
    541774    public function createDefaultSignature( &$uri , &$result , &$criteria , $original ){ 
    542775                      
    543     //Caso uma busca não retorne nenhum resultado e foi buscado pelas assinaturas do usuario logado apenas 
     776    //Caso uma busca não retorne nenhum resultado e foi buscado pelas assinaturas do usuario logado apenas 
    544777    if(count($result) <= 0 &&  
    545778            ( $original['criteria']['filter'][0] == '=' && 
     
    592825        else 
    593826        { 
    594          //Criaremos uma agenda parão 
     827         //Criaremos uma agenda parão 
    595828          $cal = array('name' => 'Calendario', 
    596                          'description' => 'Calendario Padrão', 
     829                         'description' => 'Calendario Padrão', 
    597830                         'timezone' =>  (date_default_timezone_get()) ? date_default_timezone_get() : 'America/Sao_Paulo', 
    598831                         'dtstamp' => time().'000' 
     
    681914                    continue; 
    682915                 
    683                 //Criação do ical 
     916                //Criação do ical 
    684917                $ical = null; 
    685918                $ical = new vcalendar(); 
     
    702935                                /////////////////////////////////////////////////////////////////////////// 
    703936                 
    704                 //Criação do E-mail 
     937                //Criação do E-mail 
    705938                $mail = array(); 
    706939                $mail['isHtml'] = true;   
     
    719952                                                        ),ROOTPATH.'/api/templates/notify_create_body.tpl'); 
    720953                 
    721                 //TODO: Internacionalização do Subject 
    722                 $mail['subject'] = 'Schedulableo do Calendário : '.$schedulable['summary'] .' @ '.date_format( $sTime , 'd/m/Y H:i') . ' - ' .  date_format( $eTime , 'd/m/Y H:i'); 
     954                //TODO: Internacionalização do Subject 
     955                $mail['subject'] = 'Schedulableo do Calendário : '.$schedulable['summary'] .' @ '.date_format( $sTime , 'd/m/Y H:i') . ' - ' .  date_format( $eTime , 'd/m/Y H:i'); 
    723956                $mail['from'] =  $organizer['mail']; 
    724957                $mail['to'] = $att[$i]['mail']; 
     
    759992        } 
    760993    } 
    761          
    762 //HELPERS 
    763     private static function decodeRepeat( $repeat , $start , $end ) { 
    764     require_once ROOTPATH.'/plugins/when/When.php'; 
    765  
    766     $r = new When(); 
    767     $r->recur( new DateTime( '@'.$start , new DateTimeZone('UTC') ), $repeat['frequency'] ); 
    768  
    769     foreach($repeat as $rule => $value) 
    770     {                   
    771             switch(strtoupper($rule)) 
    772             { 
    773                     case "ENDTIME": 
    774                             $r->until( new DateTime( '@'.$value ) ); 
    775                             break; 
    776                     case "COUNT": 
    777                             $r->count( $value ); 
    778                             break; 
    779                     case "INTERVAL": 
    780                             $r->interval( $value ); 
    781                             break; 
    782                     case "BYDAY": 
    783                             if( !is_array( $value ) ) 
    784                                 $value = explode( ',' , $value ); 
    785                             $r->byday( $value ); 
    786                             break; 
    787                     case "BYMONTHDAY": 
    788                            if( !is_array( $value ) ) 
    789                                 $value = explode(',' , $value ); 
    790                             $r->bymonthday($value); 
    791                             break; 
    792                     case "BYYEARDAY": 
    793                               if( !is_array( $value ) ) 
    794                                 $value = explode(',', $value ); 
    795                             $r->byyearday( $value ); 
    796                             break; 
    797                     case "BYWEEKNO": 
    798                              if(!is_array( $value )) 
    799                                 $value = explode( ',', $value ); 
    800                             $r->byweekno( $value ); 
    801                             break; 
    802                     case "BYMONTH": 
    803                              if( !is_array( $value ) ) 
    804                                 $value = explode( ',', $value ); 
    805                             $r->bymonth( $value ); 
    806                             break; 
    807                     case "BYSETPOS": 
    808                              if( !is_array( $value ) ) 
    809                                 $value = explode( ',' , $value ); 
    810                             $r->bysetpos( $value ); 
    811                             break; 
    812                     case "WKST": 
    813                             $r->wkst( $value ); 
    814                             break; 
    815             } 
    816     } 
    817  
    818     $return = array(); 
    819  
    820     while($result = $r->next()) 
    821     {  
    822        $u = $result->format('U'); 
    823        if( $u  > $end ) //data da repetição atual maior que a data final da busca do usuario ? 
    824            break; 
    825  
    826       $return[] =  $u; 
    827     } 
    828  
    829     return $return; 
    830 } 
     994 
    831995    private function _makeUid() { 
    832996 
     
    8881052    private static function schedulable2calendarToObject($Schedulable) 
    8891053    { 
    890       return Controller::service('PostgreSQL')->execResultSql('SELECT calendar_to_calendar_object.id as calendar_to_calendar_Object , calendar.name as calendar_name ,calendar.location as calendar_location FROM calendar_to_calendar_object , calendar , calendar_signature'  
     1054      return Controller::service('PostgreSQL')->execResultSql('SELECT calendar_to_calendar_object.id as calendar_to_calendar_Object , calendar.name as calendar_name ,calendar.location as calendar_location, calendar.id as calendar_id FROM calendar_to_calendar_object , calendar , calendar_signature'  
    8911055                .' WHERE calendar_signature.user_uidnumber = '.$_SESSION['wallet']['user']['uidNumber'] 
    8921056                .' AND calendar_signature.is_owner = 1' 
  • trunk/prototype/modules/calendar/js

    • Property svn:ignore
      •  

        old new  
        22._init.js 
        33._calendar.date.js 
         4.calendar.codecs.js.kate-swp 
  • trunk/prototype/modules/calendar/js/calendar.codecs.js

    r5652 r5715  
    22   
    33    init: function(){ 
    4                 this.moduleName = 'expressoCalendar'; 
     4                this.moduleName = 'expressoCalendar';  
    55                this.me = DataLayer.dispatch( "me" ); 
    66                 
     
    99                this.isDaylightSaving = Timezone.daylightSaving; 
    1010                this.load();       
    11     }, 
     11    },              
    1212   
    1313    load: function(){ 
     
    564564                                return returns; 
    565565                        }; 
    566                                                  
     566                                                                 
    567567                    return { 
    568568                            "class": objEvent["class"], 
    569569                            id: objEvent.id, 
     570                            repeat: encodeRepeat( objEvent.repeat ), 
    570571                            location: objEvent.location, 
    571572                            category: objEvent.category, 
     
    605606                                                        receiveNotification : attend.receiveNotification, 
    606607                                                        alarms : $.map(attend.alarms || [], function( alarm ){ 
    607                                                                 //TODO - Atualizar cach cliente em conceito aninhados de camada 2 
    608                                                                 var alarmEvent = DataLayer.get('alarm', alarm) 
    609                                                                 return !!alarmEvent ? alarmEvent: (null); 
     608                                                                return DataLayer.get('alarm', alarm); 
    610609                                                        }) 
    611610                                                }; 
     
    643642                            me: !!participantInfo.user ? DataLayer.merge(participantInfo.user, me) : DataLayer.merge(this.isShared ? this.organizer :  me, {acl:  !this.isShared ? 'rowi' : Calendar.signatureOf[objEvent.calendar].permission.aclValues, delegatedFrom: 0, receiveNotification: 1}), 
    644643                                delegatedFrom: delegatedFrom, 
     644                                 
    645645                                statusParticipants: statusParticipants 
    646646                        }; 
     
    650650}); 
    651651 
    652  
     652function decodeRepeat ( form ) { 
     653 
     654        var patati = {}; 
     655         
     656        if( form.repeatId ) 
     657            patati['id'] = form.repeatId; 
     658 
     659        patati['frequency'] = form.frequency; 
     660 
     661        patati['bymonthday'] = patati['byyearday'] = patati['byday'] = ''; 
     662         
     663        patati['interval'] = patati['endTime'] = patati['count'] = patati['startTime'] = 0; 
     664         
     665        if( form.frequency === 'none' ) 
     666            return( patati ); 
     667         
     668        var day = []; 
     669 
     670        $("input[type=checkbox][name='repeatweekly[]']:checked").each(function() {  
     671                day[ day.length ] = $(this).val(); 
     672        }); 
     673 
     674        patati['byday'] = day.join(','); 
     675 
     676        var formatString = ( typeof form.allDay !== "undefined" && !!form.allDay )? User.preferences.dateFormat+" HH:mm" : User.preferences.dateFormat + " " + User.preferences.hourFormat; 
     677 
     678        var date = Date.parseExact( form.startDate + (!!form.allDay ? " 00:00": " "+$.trim(form.startHour)) , formatString ).add( { days: 1 } ).toString('yyyy-MM-dd HH:mm:00'); 
     679         
     680        patati['startTime'] = date.toString('yyyy-MM-dd HH:mm:00'); 
     681         
     682        if( !patati['byday'] ) 
     683              switch(form.frequency) { 
     684              case 'weekly':       
     685                      break; 
     686              case 'daily': 
     687                      break; 
     688              case 'monthly': 
     689                      patati['bymonthday'] = date.getDate(); 
     690                      break; 
     691              case 'yearly': 
     692                      patati['byyearday'] = date.getDayOfYear(); 
     693                      break; 
     694              default : 
     695                      return patati; 
     696              } 
     697 
     698        if (($(".endRepeat").val() == 'occurrences'))  
     699                patati['count'] = $(".occurrencesEnd").val();  
     700         
     701        if (($(".endRepeat").val() == 'customDate')) 
     702                patati['endTime'] = Date.parseExact( $(".customDateEnd").val() + (!!form.allDay ? " 00:00": " "+$.trim(form.endHour)) , formatString ).toString('yyyy-MM-dd HH:mm:00'); 
     703         
     704        patati['interval']  = $(".eventInterval").val(); 
     705 
     706        /** 
     707        wkst = [ 'MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU' ] 
     708        weekno = number 
     709        minute = number 
     710        second = number 
     711        yearday = number 
     712        monthday = number 
     713        setpos = number 
     714        day = number 
     715        hour = number 
     716        interval = number 
     717        frequency = [ 'monthly', 'daily', 'weekly', 'yearly', 'hourly', 'minutely', 'secondly' ] 
     718        endTime = milliseconds 
     719    */     
     720    return( patati ); 
     721       
     722} 
     723 
     724 
     725 
     726function encodeRepeat( repeat ){ 
     727   
     728        if( !repeat ) 
     729            return( false ); 
     730 
     731        return DataLayer.get( 'repeat', repeat ); 
     732} 
    653733 
    654734DataLayer.codec( "schedulable", "detail", { 
     
    674754                                  startTime: Date.parseExact(form.startDate + (!!form.allDay ? " 00:00": " "+$.trim(form.startHour)) , formatString ).toString('yyyy-MM-dd HH:mm:00'), 
    675755                                  endTime:  Date.parseExact(form.endDate + ( !!form.allDay ? " 00:00": " "+$.trim(form.endHour)), formatString ).toString('yyyy-MM-dd HH:mm:00'),  //+ (!!form.allDay ? 86400000 : 0) , 
    676                                   allDay: ( !!form.allDay ? 1 : 0 ), 
     756                                  allDay: ( !!form.allDay ? 1 : 0 ),        
    677757                              id: form.idEvent, 
    678758                              location: form.location, 
     
    685765                                                return {attachment: attachment} 
    686766                                  }), 
     767                              repeat: this.decodeRepeat( form ), 
    687768                              participants: $.map( form.attendee || [], function( attendee, i ){ 
    688769 
     
    722803    }, 
    723804 
     805 
    724806    encoder: function( evtObj ){ 
    725807         
    726         if(!(!!evtObj)) 
    727                 return undefined; 
    728  
    729         var notArray = false; 
    730        
    731         if( notArray = $.type(evtObj) !== "array" ) 
    732             evtObj = [ evtObj ]; 
    733  
    734         var pref = User.preferences; 
    735  
    736         var res =  DataLayer.encode('schedulable:preview', evtObj); 
    737  
    738         if( !notArray ){ 
    739             var dates = {}; 
    740  
    741             for (var i=0; i < res.length; i++) { 
    742  
    743                     var startDate = Date.parseExact( res[i]['startDate'], User.preferences.dateFormat ); 
    744                     var endDate   = Date.parseExact( res[i]['endDate'], User.preferences.dateFormat ); 
    745  
    746                     var counter   = startDate.clone(); 
    747  
    748                     while (counter.compareTo(startDate) == 0) { 
    749  
    750                             if (!dates[counter.toString(User.preferences.dateFormat)])  
    751                                         dates[counter.toString(User.preferences.dateFormat)] = { startDate:false, events:[] }; 
    752                             if (!dates[counter.toString(User.preferences.dateFormat)].startDate)  
    753                                         dates[counter.toString(User.preferences.dateFormat)].startDate = counter.toString(User.preferences.dateFormat); 
    754  
    755                             dates[counter.toString(User.preferences.dateFormat)].events.push(res[i]); 
    756                             counter.addDays(-1); 
    757                     }  
    758             } 
    759             res = { events_list: dates, 
    760                                 count : res.length 
    761                         }; 
    762         } 
    763  
    764         return notArray ? res[0] : res; 
     808                if(!(!!evtObj)) 
     809                        return undefined; 
     810 
     811                var notArray = false; 
     812                   
     813                if( notArray = $.type(evtObj) !== "array" ) 
     814                        evtObj = [ evtObj ]; 
     815 
     816                var pref = User.preferences; 
     817 
     818                var res =  DataLayer.encode('schedulable:preview', evtObj); 
     819 
     820                if( !notArray ){ 
     821                        var dates = {}; 
     822 
     823                        for (var i=0; i < res.length; i++) { 
     824                           
     825                                var startDate = Date.parseExact( res[i]['startDate'], User.preferences.dateFormat ); 
     826                                var endDate   = Date.parseExact( res[i]['endDate'], User.preferences.dateFormat ); 
     827                           
     828                                var duration = parseInt( endDate.getTime() ) - parseInt( startDate.getTime() ); 
     829                 
     830                                var occurrences = [ startDate.getTime() ]; 
     831                                 
     832                                if( res[i].occurrences ) 
     833                                { 
     834                                    occurrences = res[i].occurrences; 
     835                                } 
     836 
     837                                for( var ii = 0; ii < occurrences.length; ii++ ) 
     838                                { 
     839                                    var currentDate = new Date( occurrences[ii] ); 
     840                                    var counter = currentDate.clone(); 
     841                                     
     842                                    var res2 = $.extend( {}, res[i], {'startDate': currentDate.toString( User.preferences.dateFormat ), 'endDate': new Date( occurrences[ii] + duration ).toString( User.preferences.dateFormat ) } ); 
     843                                   
     844                                    while (counter.compareTo( currentDate ) == 0) { 
     845 
     846                                            if (!dates[counter.toString(User.preferences.dateFormat)])  
     847                                                    dates[counter.toString(User.preferences.dateFormat)] = { startDate:false, events:[] }; 
     848                                            if (!dates[counter.toString(User.preferences.dateFormat)].startDate)  
     849                                                    dates[counter.toString(User.preferences.dateFormat)].startDate = counter.toString(User.preferences.dateFormat); 
     850 
     851                                            dates[counter.toString(User.preferences.dateFormat)].events.push(res2); 
     852                                            counter.addDays(-1); 
     853                                    }       
     854                                } 
     855                        } 
     856                        res = { events_list: dates, 
     857                                        count : res.length 
     858                                }; 
     859                } 
     860 
     861                return notArray ? res[0] : res; 
    765862    } 
    766863 
     
    823920            return( false ); 
    824921 
    825 //       if( notArray = $.type(evtObj) !== "array" ) 
    826 //        evtObj = [ evtObj ]; 
    827 //      alert( evtObj ); 
    828922        var filtered = evtObj; 
    829          
    830         // repeat:{ 
    831 //        frequency: "weekly", 
    832 //        endTime: Date.parse("+10 days").getTime(), 
    833 //        interval: 3, 
    834 //        byday: 3, 
    835 //        bysecond: 3, 
    836 //        byminute: 3, 
    837 //        bymonthday: 3, 
    838 //        byyearday: 3, 
    839 //        byweekno: 3, 
    840 //        bysetpos: 3, 
    841 //        wkst: "monday"/*, 
    842 //        duration: true*/ 
    843 //       } 
    844  
    845 //      $.each(evtObj, function( index, evt ){ 
    846  
    847 //              alert( dump(!!evt.repeat) ); 
    848  
    849 //              if( evt && !!evt.repeat && (evt.startTime < filter.end || (evt.repeat.endTime || 0) > filter.start ) ) 
    850 //              { 
    851 // //               var interval = evt.repeat.interval; 
    852923//  
    853 //                  var current = new Date( evt.startTime ); 
    854 //                  var begin = new Date( filter.start ); 
    855 //                  var end = new Date( filter.end ); 
    856 //                  var offset = evt.endTime - evt.startTime; 
    857 //  
    858 //                  var ocurrence = []; 
    859 //  
    860 //                  while( Date.compare( current, begin ) !== 1 ) 
    861 //                      current = current.parse( "+" + evt.repeat.interval + " " + frequency + "s" ); 
    862 //  
    863 //                  while( current.before( end ) && (ocurrence[ ocurrence.length ] = current) ) 
    864 //                      current = current.parse( "+" + evt.repeat.interval + " " + frequency + "s" ); 
    865 //  
    866 //                  for( var i = 0; i < ocurrences.length; i++ ) 
    867 //                      filtered[ filtered.length ] = { URI: evt.URI, 
    868 //                                                      summary: evt.summary, 
    869 //                                                      start: new Date( ocurrences[i] ), 
    870 //                                                      end: new Date( ocurrences[i] + offset ), 
    871 //                                                      allDay: evt.allDay }; 
    872 //  
    873 // //               switch( evt.repeat.frequency ) 
    874 // //               { 
    875 // //                 case "yearly":   interval *= 12; 
    876 // //                 case "monthly":  interval *= 30; //TODO: get the month variant 
    877 // //                 case "weekly":   interval *= 7; 
    878 // //                 case "daily":    interval *= 24; 
    879 // //                 case "hourly":   interval *= 60; 
    880 // //                 case "minutely": interval *= 60;  
    881 // //                 case "secondly": interval *= 1000; 
    882 // //               } 
    883 // //              
    884 // //               var rest = ( filter.start - evt.startTime ) % interval; 
    885 // //  
    886 // //               var offset = evt.endTime - evt.startTime; 
    887 // //  
    888 // //               if( rest < offset ) 
    889 // //               { 
    890 // //                   var freq = Math.floor( offset - rest / interval ); 
    891 // //  
    892 // //                    
    893 // //  
    894 // //                   for( var i = 0; i < freq; i++ ) 
    895 // //                   { 
    896 // //                        var ocurrence = filter.start + rest + ( interval * i ); 
    897 // //  
    898 // //                         
    899 // //                   } 
    900 // //  
    901 // //                    
    902 // //               } 
    903 //              } 
    904  
    905 //              if( parseInt( evt.endTime ) > filter[1][0][2] || parseInt( evt.startTime ) < filter[1][1][2] ) 
    906 //                  filtered[ filtered.length ] = evt; 
    907 //  
    908 //      }); 
    909  
    910924        var grouped = {}; 
    911925 
     
    922936                var calendar = DataLayer.get('calendar', evt.calendar); 
    923937                 
    924                 var eventEditable = function(idEvent){ 
     938                var eventEditable = function(idEvent, isRecurrence){ 
    925939                        if(Calendar.signatureOf[calendar.id].isOwner == "1"){ 
    926940                                var attendee = {}; 
     
    928942                                        attendee = DataLayer.get('participant', evt.participants[i]); 
    929943                                                if(attendee.user == User.me.id) 
    930                                                         return (attendee.acl.indexOf('w') >= 0 || attendee.acl.indexOf('o') >= 0 ) ? {selectable: true, className: 'fullcalendar-context-menu  event-id-'+idEvent} : {editable: false, selectable: true ,className: 'blocked-event-permision  fullcalendar-not-context-menu event-id-'+idEvent}; 
     944                                                        return (attendee.acl.indexOf('w') >= 0 || attendee.acl.indexOf('o') >= 0 ) ? {selectable: true, className: 'fullcalendar-context-menu  event-id-'+idEvent, editable: !isRecurrence} : { editable: false, selectable: true ,className: 'blocked-event-permision  fullcalendar-not-context-menu event-id-'+idEvent}; 
    931945                                } 
    932                                 return {editable: false, className: 'blocked-event-permision  fullcalendar-not-context-menu event-id-'+idEvent,  selectable: true}; 
     946                                return {editable: false, className: 'blocked-event-permision  fullcalendar-not-context-menu event-id-'+idEvent,  selectable: true, disableDragging: isRecurrence }; 
    933947                        } 
    934948                        else{ 
     
    943957                                }                                
    944958                                return DataLayer.merge({ 
    945                                         editable: aclSignature.acl['write'], 
     959                                        editable: aclSignature.acl['write'] && !isRecurrence, 
    946960                                        disableResizing : (((aclSignature.acl['busy'] && !aclSignature.acl['write']) || (!aclSignature.acl['write'] && aclSignature.acl['read'])) ? true : false), 
    947961                                        disableDragging  : (((aclSignature.acl['busy'] && !aclSignature.acl['write']) || (!aclSignature.acl['write'] && aclSignature.acl['read'])) ? true: false), 
     
    951965                         
    952966                } 
     967                 
     968                var duration = parseInt( evt.endTime ) - parseInt( evt.startTime ), isRepeat = false; 
     969                 
     970                var occurrences = [ evt.startTime ]; 
     971                 
     972                if( evt.occurrences ) 
     973                { 
     974                    isRepeat = true; 
     975                    occurrences = evt.occurrences; 
     976                } 
    953977                   
    954                 grouped[ evt.calendar ].push( DataLayer.merge({ id: evt.URI || evt.id, 
    955                                                 title: Encoder.htmlDecode(evt.summary), 
    956                                                 start: Timezone.getDateCalendar(new Date(parseInt( evt.startTime )), calendar.timezone,  !!evt.DayLigth ? evt.DayLigth.calendar.startTime : Timezone.daylightSaving), 
    957                                                 end:   Timezone.getDateCalendar(new Date(parseInt( evt.endTime ) - (!!parseInt(evt.allDay) ? 86400000 : 0)), calendar.timezone, !!evt.DayLigth ? evt.DayLigth.calendar.startTime : Timezone.daylightSaving), 
    958                                                 allDay: parseInt( evt.allDay ) }, eventEditable(evt.id) ) ); 
     978                for( var i = 0; i < occurrences.length; i++ ) 
     979                    grouped[ evt.calendar ].push( DataLayer.merge({ id: evt.URI || evt.id, 
     980                                                    title: Encoder.htmlDecode(evt.summary), 
     981                                                    start: Timezone.getDateCalendar(new Date( parseInt( occurrences[i] ) ), calendar.timezone,  !!evt.DayLigth ? evt.DayLigth.calendar.startTime : Timezone.daylightSaving), 
     982                                                    end:   Timezone.getDateCalendar(new Date( parseInt( occurrences[i] ) + duration - (!!parseInt(evt.allDay) ? 86400000 : 0)), calendar.timezone, !!evt.DayLigth ? evt.DayLigth.calendar.startTime : Timezone.daylightSaving), 
     983                                                    allDay: parseInt( evt.allDay ) }, eventEditable(evt.id, isRepeat ) ) ); 
    959984        }); 
    960985 
  • trunk/prototype/modules/calendar/js/helpers.js

    r5641 r5715  
    361361                         
    362362                } 
    363                  
     363 
     364            DataLayer.render( 'templates/event_repeat.ejs', {event:objEvent}, function( repeatHtml ){ 
     365 
     366                        UI.dialogs.addEvent.find('#calendar_addevent_details3').html(repeatHtml); 
     367                        $(".date").datepicker(); 
     368                   
     369                        if(objEvent.repeat)  
     370                        { 
     371                             if( objEvent.repeat['id'] ) 
     372                             { 
     373                                $("[name='repeatId']:last").val( objEvent.repeat['id'] ); 
     374                             } 
     375 
     376                             if( objEvent.repeat['frequency'] !== 'none' ) 
     377                             { 
     378                                if( objEvent.repeat['startTime'] && objEvent.repeat['startTime'] !== "0" ) 
     379                                { 
     380                                      $("[name='startOptions'] [value='customDate']:last").attr( 'selected', 'selected' ); 
     381                                      $("[name='start']:last").val(new Date( parseInt(objEvent.repeat['startTime']) ).toString( User.preferences.dateFormat ) ); 
     382                                } 
     383                                else 
     384                                { 
     385                                      $("[name='start']:last").val($("[name='startDate']:last").val());      
     386                                      $("[name='start']:last").readOnly=true; 
     387                                      $("[name='start']:last").datepicker("disable"); 
     388                                } 
     389                               
     390                                $(".finish_event").removeClass("hidden"); 
     391 
     392                                if(objEvent.repeat['endTime'] && objEvent.repeat['endTime'] !== "0" )  
     393                                { 
     394                                        //$("[name='occurrences']").addClass("hidden"); 
     395                                        $(".customDateEnd").removeClass("hidden"); 
     396                                                        $(".endRepeat option[value='customDate']").attr('selected', 'selected')                                          
     397                                        $(".customDateEnd").val( new Date( parseInt(objEvent.repeat['endTime']) )/*.setTimezoneOffset( Timezone.timezone( objEvent.timezone ) )*/.toString( User.preferences.dateFormat ) );   
     398                                } 
     399                                else if (objEvent.repeat['count'] && objEvent.repeat['count'] !== "0" ) { 
     400                                        $(".endRepeat option[value='occurrences']").attr('selected', 'selected');                                                
     401                                        $(".occurrencesEnd").removeClass("hidden"); 
     402                                        $(".occurrencesEnd").val(objEvent.repeat['count']);                                              
     403                                } 
     404                               
     405                                switch ( objEvent.repeat['frequency'] ) 
     406                                { 
     407                                    case "daily": 
     408                                            $(".event-repeat-container:last").find(".repeat-in").find(".interval").html("Dia(s)"); 
     409                                            $(".frequency option[value='daily']").attr('selected', 'selected'); 
     410                                            break; 
     411                                    case "weekly": 
     412                                            $(".event-repeat-container:last").find(".repeat-in").find(".interval").html("Semana(s)"); 
     413                                            $(".frequency option[value='weekly']").attr('selected', 'selected'); 
     414                                            objEvent.repeat['interval'] ? $(".event-repeat-container:last").find(".repeat-in").find(".eventInterval").val(objEvent.repeat['interval']) : $(".event-repeat-container:last").find(".repeat-in").find(".eventInterval").val("0"); 
     415                                             
     416                                            $(".event-repeat-weekly").removeClass("hidden"); 
     417                                             
     418                                            var day = []; 
     419                                             
     420                                            if( objEvent.repeat.byday ) 
     421                                                day = objEvent.repeat.byday.split(','); 
     422                                             
     423                                            for(i=0; i<day.length; i++)  
     424                                                    $(".event-repeat-weekly [value='" + day[i] + "']").attr("checked","checked"); 
     425                                             
     426                                            break; 
     427                                    case "monthly": 
     428                                            $(".event-repeat-container:last").find(".repeat-in").find(".interval").html("Mes(s)"); 
     429                                            $(".frequency option[value='monthly']").attr('selected', 'selected') 
     430                                            $(".event-repeat-monthly:last").removeClass("hidden").find("input[type=radio][name=repeatmonthyType]").click(function(){ 
     431                                                    if($("input[type=radio][name=repeatmonthyType]:checked").val() == "1") 
     432                                                            $(".event-repeat-weekly:last").removeClass("hidden"); 
     433                                                    else 
     434                                                            $(".event-repeat-weekly:last").addClass("hidden"); 
     435                                            }); 
     436                                            if($("input[type=radio][name=repeatmonthyType]:checked").val() == "1") 
     437                                                    $(".event-repeat-weekly:last").removeClass("hidden"); 
     438                                            else 
     439                                                    $(".event-repeat-weekly:last").addClass("hidden"); 
     440                                            break; 
     441                                    case "yearly": 
     442                                            $(".event-repeat-container:last").find(".repeat-in").find(".interval").html("Ano(s)"); 
     443                                            $(".frequency option[value='yearly']").attr('selected', 'selected') 
     444                                            break;       
     445                                } 
     446                            } 
     447                        } 
     448                        else { 
     449                                $(".endRepeat option[value='never']").attr('selected', 'selected'); 
     450                        } 
     451 
     452 
     453                        $(".event-repeat-container:last").find(".repeat-in").find("[name=startOptions]").change(function(){                                        
     454 
     455            if($(this).find("option:selected").val() == "Today"){ 
     456                                $("[name='start']:last").val($("[name='startDate']:last").val()); 
     457                                $("[name='start']:last").readOnly=true; 
     458                                $("[name='start']:last").datepicker("disable"); 
     459                            } 
     460                            else{ 
     461                                $("[name='start']:last").readOnly=false; 
     462                                $("[name='start']:last").datepicker("enable"); 
     463                            } 
     464                        }); 
     465                        $(".event-repeat-container:last").find(".repeat-in").find("[name=endOptions]").change(function(){                                        
     466                            if($(this).find("option:selected").val() == "never"){ 
     467                                $("[name='occurrences']").addClass("hidden"); 
     468                                $("[name='end']:last").addClass("hidden"); 
     469                            } 
     470                            else if($(this).find("option:selected").val() == "customDate"){ 
     471                                $("[name='occurrences']").addClass("hidden"); 
     472                                $("[name='end']:last").removeClass("hidden");     
     473                            } 
     474                            else{ 
     475                                $("[name='end']:last").addClass("hidden"); 
     476                                $("[name='occurrences']").removeClass("hidden");                                         
     477                            } 
     478                        }); 
     479                         
     480                        $("[name='frequency']:last").change(function () { 
     481                                $(".frequency-option").addClass("hidden"); 
     482                                if($(this).val() == "none"){ 
     483                                        $(".repeat-in").addClass("hidden"); 
     484                                        return; 
     485                                }else{ 
     486                                    $(".repeat-in").removeClass("hidden"); 
     487                                    $("[name='start']:last").val($("[name='startDate']:last").val()); 
     488                                } 
     489                  
     490                                  
     491                                switch($(this).val()){ 
     492                    case "daily": 
     493                        $(".event-repeat-container:last").find(".repeat-in").find(".interval").html("Dia(s)"); 
     494                        break; 
     495                                        case "weekly": 
     496                        $(".event-repeat-container:last").find(".repeat-in").find(".interval").html("Semana(s)"); 
     497                                                $(".event-repeat-weekly:last").removeClass("hidden"); 
     498                                                break; 
     499                                        case "monthly": 
     500                        $(".event-repeat-container:last").find(".repeat-in").find(".interval").html("Mes(s)"); 
     501                                                $(".event-repeat-monthly:last").removeClass("hidden").find("input[type=radio][name=repeatmonthyType]").click(function(){ 
     502                                                        if($("input[type=radio][name=repeatmonthyType]:checked").val() == "1") 
     503                                                                $(".event-repeat-weekly:last").removeClass("hidden"); 
     504                                                        else 
     505                                                                $(".event-repeat-weekly:last").addClass("hidden"); 
     506                                                }); 
     507                        if($("input[type=radio][name=repeatmonthyType]:checked").val() == "1") 
     508                            $(".event-repeat-weekly:last").removeClass("hidden"); 
     509                                                else 
     510                            $(".event-repeat-weekly:last").addClass("hidden"); 
     511                                            break; 
     512                    default: 
     513                        $(".event-repeat-container:last").find(".repeat-in").find(".interval").html("Ano(s)"); 
     514                        break; 
     515                                } 
     516                                 
     517                        }); 
     518                }); 
     519 
    364520            UI.dialogs.addEvent.find('.calendar_addevent_details_lnk_timezone').click(function(e){ 
    365521                    $(this).addClass('hidden'); 
     
    627783                                        var user = DataLayer.get('user', ["=", "mail", $(this).val()]); 
    628784                                        if(!!user && user[0].id) 
    629                                                 attendees[user[0].id].name  = user[0].name; 
     785                                                attendees[user[0].id] = { name: user[0].name }; 
    630786                                         
    631787                                        /** 
  • trunk/prototype/modules/calendar/templates/event_add.ejs

    r5652 r5715  
    4949        <ul> 
    5050                <li><a href="#calendar_addevent_details2">Detalhes do evento</a></li> 
    51 <!--            <li><a href="#calendar_addevent_details3">Repetir</a></li>--> 
     51                <li><a href="#calendar_addevent_details3">Repetir</a></li> 
    5252                <li><a href="#calendar_addevent_details4">Lembretes</a></li> 
    5353                <li><a href="#calendar_addevent_details5">Anexos</a></li> 
     
    104104                 
    105105        </fieldset> 
    106 <!--     
     106 
    107107        <fieldset id="calendar_addevent_details3" class="tab-level2"> 
    108108                 
    109109        </fieldset> 
    110         --> 
     110 
    111111        <fieldset id="calendar_addevent_details4" class="tab-level2"> 
    112112                <legend class="hidden">Lembretes</legend> 
  • trunk/prototype/modules/calendar/templates/event_repeat.ejs

    r5341 r5715  
    11<fieldset id="calendar_event_repeat_form" class="event-repeat-container"> 
    22        <legend class="hidden">Repetição do evento</legend> 
     3        <input type="hidden" name="repeatId"/> 
    34         
    45        <p class="input-group"> 
    56                <label for="frequency">Repetição:</label> 
    6                 <select name="frequency"> 
    7                         <option value="dayly">Diária</option> 
     7                <select name="frequency" class="frequency"> 
     8                        <option value="none">Sem repetição</option> 
     9                        <option value="daily">Diária</option> 
    810                        <option value="weekly">Semanal</option> 
    911                        <option value="monthly">Mensal</option> 
     
    1214        </p> 
    1315         
    14         <p class="input-group"> 
    15                 <label>Repete a cada:</label> 
    16                 <!-- Dia --> 
    17                 <input type="text" name="interval" class="tiny number"><label class=""> Dias</label> 
    18         </p> 
    19          
    2016        <!-- Semana e Mês --> 
    2117 
    22          
    23         <!-- Semana --> 
    24         <p class="input-group event-repeat-weekly hidden">    
    25                 <label>Repete</label> 
    26                 <input type="checkbox" name="repeatweekly[]" value="SU"> 
    27                 <label for="repeatweekly[]">D</label> 
    28  
    29                 <input type="checkbox" name="repeatweekly[]" value="MO"> 
    30                 <label for="repeatweekly[]">S</label> 
    31  
    32                 <input type="checkbox" name="repeatweekly[]" value="TU"> 
    33                 <label for="repeatweekly[]">T</label> 
    34  
    35                 <input type="checkbox" name="repeatweekly[]" value="WE"> 
    36                 <label for="repeatweekly[]">Q</label> 
    37  
    38                 <input type="checkbox" name="repeatweekly[]" value="TH"> 
    39                 <label for="repeatweekly[]">Q</label> 
    40  
    41                 <input type="checkbox" name="repeatweekly[]" value="FR"> 
    42                 <label for="repeatweekly[]">S</label> 
    43  
    44                 <input type="checkbox" name="repeatweekly[]" value="SA"> 
    45                 <label for="repeatweekly[]">S</label> 
    46         </p> 
    47  
    4818        <!-- Mês --> 
    49         <p class="input-group event-repeat-monthly hidden">  
    50                 <label>Repete</label> 
    51                 <input type="radio" name="repeatmonthyType"> 
     19        <p class="input-group event-repeat-monthly hidden frequency-option">  
     20                <label>Mensalmente por </label> 
     21                <input type="radio" name="repeatmonthyType" value="0"> 
    5222                <label for="repeatmonthyType">dia do mês</label> 
    5323 
    54                 <input type="radio" name="repeatmonthyType"> 
     24                <input type="radio" name="repeatmonthyType" value="1"> 
    5525                <label for="repeatmonthyType">dia da semana</label> 
    5626        </p> 
    5727         
    58         <p> 
    59                 <!-- 
    60                 <label for="start">Inicia em</label> 
    61                 <input class="date" type="text" name="start"> 
    62                 --> 
    63                 <input type="checkbox" name="neverEnds" checked="checked"> 
    64                 <label for="end_event">Evento nunca termina</label> 
     28        <!-- Semana --> 
     29        <p class="input-group event-repeat-weekly hidden frequency-option">    
     30                <label>Toda </label> 
     31                <input type="checkbox" name="repeatweekly[]" value="SU"> 
     32                <label for="repeatweekly[]">Domingo</label> 
     33 
     34                <input type="checkbox" name="repeatweekly[]" value="MO"> 
     35                <label for="repeatweekly[]">Segunda</label> 
     36 
     37                <input type="checkbox" name="repeatweekly[]" value="TU"> 
     38                <label for="repeatweekly[]">Terça</label> 
     39 
     40                <input type="checkbox" name="repeatweekly[]" value="WE"> 
     41                <label for="repeatweekly[]">Quarta</label> 
     42 
     43                <input type="checkbox" name="repeatweekly[]" value="TH"> 
     44                <label for="repeatweekly[]">Quinta</label> 
     45 
     46                <input type="checkbox" name="repeatweekly[]" value="FR"> 
     47                <label for="repeatweekly[]">Sexta</label> 
     48 
     49                <input type="checkbox" name="repeatweekly[]" value="SA"> 
     50                <label for="repeatweekly[]">Sabado</label> 
    6551        </p> 
    66         <label class="hidden label_finish_event">Termina</label> 
    67         <p class="hidden input-group finish_event"> 
     52         
     53        <p class="input-group finish_event repeat-in hidden"> 
     54                <!-- <span class="input-group"> 
     55                        <label for="start">A repetição inicia</label> 
     56                        <select name="startOptions" class="startOptions"> 
     57                            <option value="Today">Hoje</option> 
     58                            <option value="customDate">Na Data Selecionada</option> 
     59                        </select> 
     60                        <input class="date startDate" type="text" name="start" readonly> 
     61                </span> --> 
     62        </p> 
     63        <p class="input-group finish_event repeat-in hidden"> 
    6864                <span class="input-group"> 
    69                         <input type="radio" name="repeat_finish" value="date_fixed"> 
    70                         <label>Em</label>  
    71                         <input type="text" name="" class="date"> 
     65                        <label class="label_finish_event">A repetição</label> 
     66                        <!--<input type="radio" name="repeat_finish" value="date_fixed">--> 
     67                        <select name="endOptions" class="endRepeat"> 
     68                            <option value="never">Nunca termina</option> 
     69                            <option value="customDate">Termina na Data Selecionada</option> 
     70                            <option value="occurrences">Termina Após n Ocorrencias</option> 
     71                        </select> 
     72                                                <input type="text" name="end" class="date customDateEnd hidden"> 
     73                        <input type="text" name="occurrences" class="tiny number occurrencesEnd hidden"> 
     74                        <label name="occurrences" class="hidden">Ocorrências</label> 
    7275                </span> 
    73                  
    74                 <span class="input-group"> 
    75                         <input type="radio" name="repeat_finish" value="occurrences"> 
    76                         <label>Após</label> 
    77                         <input type="text" name="" class="tiny number"> 
    78                         <label>Ocorrências</label> 
     76        </p> 
     77        <p class="input-group finish_event repeat-in hidden"> 
     78                <span class="input-group"> 
     79                        <label>Tendo intervalo de</label> 
     80                        <input type="text" name="" class="tiny number eventInterval" value="0"> 
     81                        <label class="interval"></label> 
    7982                </span> 
    80         </p> 
    81         <button class="test-recurrence" onclick="recurrence();">Gera a repetição então, vamo ver!</button> 
     83        </p>                 
     84        <!--<button class="test-recurrence" onclick="recurrence();">Gera a repetição então, vamo ver!</button>--> 
    8285<!--    <label for="calendar_event_repeat_summary">Resumo:</label> 
    8386    <span>Semanal: cada quinta-feira<span>--> 
  • trunk/prototype/services/iCal.php

    r5682 r5715  
    3737                     
    3838                       $vevent = $ical->newComponent( 'vevent' ); 
    39                          
     39                                         
    4040                       $vevent->setProperty( 'summary' , $v['summary'] ); 
    4141                       $vevent->setProperty( 'description' , $v['description'] ); 
     
    4545                       $timezone = new DateTimeZone('UTC'); 
    4646                       $apTimezone = self::nomalizeTZID(( isset($v['timezone']) && $v['timezone'] != 'null' ) ? $v['timezone'] : $params['defaultTZI']); 
    47                           
     47                       $apTimezoneOBJ = new DateTimeZone($apTimezone); 
     48                        
    4849                       $sTime = new DateTime( '@'.(int)($v['startTime'] / 1000) , $timezone );                                     
    49                        $sTime->setTimezone(new DateTimeZone($apTimezone)); 
     50                       $sTime->setTimezone($apTimezoneOBJ); 
    5051                       $eTime = new DateTime( '@'.(int)($v['endTime'] / 1000) , $timezone );   
    51                        $eTime->setTimezone(new DateTimeZone($apTimezone)); 
     52                       $eTime->setTimezone($apTimezoneOBJ); 
     53                        
     54                       if(isset($v['repeat'])) 
     55                       { 
     56                           $repeat = array(); 
     57                            
     58                           foreach ($v['repeat'] as $ir => $rv)  
     59                           { 
     60                               if($rv) 
     61                               { 
     62                                   if($ir == 'frequency') 
     63                                      $repeat['FREQ'] =  $rv; 
     64                                   else if($ir == 'endTime' ) 
     65                                   { 
     66                                       $time = new DateTime( '@'.(int)($rv / 1000) , $timezone );                                     
     67                                       $time->setTimezone($apTimezoneOBJ); 
     68                                       $repeat['until'] = $time->format(DATE_RFC822); 
     69                                   } 
     70                                   else if($ir == 'count') 
     71                                    $repeat[$ir] = $rv; 
     72                                   else if($ir !== 'schedulable' && $ir !== 'id' && $ir !== 'startTime') 
     73                                    $repeat[$ir] = explode(',', $rv); 
     74                               } 
     75                           } 
     76                           
     77                           $vevent->setProperty('rrule' , $repeat); 
     78                       } 
    5279                        
    5380                       if( isset($v['allDay']) && $v['allDay'] == 1 ) 
     
    757784                    $repeat['schedulable'] = $eventID; 
    758785                    foreach($rrule as $i => $v) 
    759                        $repeat[strtolower($i)] = $v; 
    760  
    761                     //$interation['repeat://'.$repeatID] = $repeat; 
     786                    { 
     787                        if(strtolower($i) == 'freq') 
     788                            $repeat['frequency'] = $v; 
     789                        else if(strtolower($i) == 'until') 
     790                            $repeat['endTime'] = $v; 
     791                        else 
     792                            $repeat[strtolower($i)] = $v; 
     793                    } 
     794                     
     795                    $interation['repeat://'.$repeatID] = $repeat; 
    762796                } 
    763797 
Note: See TracChangeset for help on using the changeset viewer.