M\á:l‹°;ZfbJôØèÞ®^—X£ß (qª·vÓIÍnÛ³séRÈEÜ]ð>=½ô €“²ñ–ïsHƒR<¿×™¦.¤yÈrHl‚·üêãpÞ´-)QAù€pëœ;p:üº\jcŠ1OoyDуö.ÏMO“|c€gIWå® üªßé(R6ëqö©Hs¦ôÐX½9ÂŽð[C–:•ƒ¼OeDíw•¨‚¿ÝVJoÿ†ݵÙ9T©uìth`»¿ ½ŠÐÊ7ˆ “«ƒ’ ÊÅl*t2Fä,‹a�)YÖÞó�Äò‘´_¿©,Û¾óFðîƒAßà¶p™îT<áJ®#eÿf ¦ÿ( ÷Ú˜Cš1°R ’‡EÖ$Œ çûÄ4FÜ&>‡²äFöÝ„§¡J»ù�瘗H؉ÀÚrÊÉÑ„µQ᱊p2N Eç�δz$kîõâ›O0SæÍTß¡ÏS™¬UQYáæ1=7¤²ZŒÎ5Ò¿â\˜YX¨ ®±þÚ0�ÊͪŒìˆO©w?¹]+ÿ¡äîÓö$DV:†uˉÀHs<˜0âÀ©Rs ùà²,Õªf)kÌô´ÌɱBÔ7ay!‚ñ�>RBÅú#ž\u~;xÆ60�”´ȴʈvÓ7+/ _iý2"�!ó$>,d–‘ÏK #vxÒ»ÑøÚŸ*®‘Áñʳ�*¨€ ¥üŒŸÏ3f€•lQŽâ±ÑIx¦:"¬y®÷®�Àºâ ºî†yw%h¾Hˆ1 ÊÞï�/ÑøóîÃâ1}yl†NëyMÏK #vxÒ»ÑøÚŸ*®‘Þ|i€ÿ¹Pü0ôC©qˆ7i'”m¤zÔà°”ŸÍð®P¹°ÄäÀØÑ|‚jèäD`ƒ‰Îºu�É=!ÒìŒFµLI„UŒ¼�d`ÙÔ%Œ>r¿DÐ~“SE²3AoÑçX«5ÎÙØWÖe.Â@ 1Îh’§I¾½á¨Ké ¥ŒÒo±*–½"Þ¢îèP>é)1({qÎÕ�QèÒÙ†·Î<\öþƒƒø<–i5@€’,¸£M•ª£'gCSlR Ö¸wÀ‘“¾}vÛ²Ä+/fS2D¼ôz�v¨\“¦·�süY�•3/tÔ?ÀK*#r’¢çb“òe„£xͯܮ±òÞ¸1è<™"I¾[d[¶3êhнA ä¶´/;Á¡uèyÈf È,S[?ð–^X1jðHo¬OðL¨­½=[º®ò¼‘Êi3SÝÔ íhG'†goh„öfH�¯¥IM}˜ˆ� øÿ�Ø1¨»;ì×ôËÄ¥¼ÆX@ÕaE{ý>xÇ8=¡ çâ/®ÛJz÷}²¥Dl x‘­åËØ³d´ }ô¾ìï2——Ô±aqìh@.Gqö¨úBêRÖnŽ¡äòçꌅ|SGÑÓ¬6ÐÌžÓ7%"¢-³Jm/XB|"­ÉŽ~àÃÂx”àÙrƒÙ¬‰xi+~àÛ^ÔNNGöµ-’!^Àñ47å�åf$AÆP[FÚæM( AˆÇegª¨”Œ„;Qò®/Ãøý÷ßr¦¦`ʧƒi?–„‰ûþ‹lk̪Só±™ÕÈ?~‘ñ]6Î(îwÆäe±Ýÿ�Ø1¨»;ì×ôËÄ¥¼ÆX@ÕaE{ý>xÇ8=¡c ×j�ø{×X\Œ­?–„‰ûþ‹lk̪Só±™ÕRˆJ”FijYT‡Rë¬W‡å�åf$AÆP[FÚæM( AˆÇegª¨”Œ„;Qò®/ík ·”¸4F<þÔXgBnHìpp¼ø’Å ›f$Š£l�‹cXÙß z]¹øî(Û?ôþíùÝdÕ¡„}¦úÝnݯç ‡.ì£:~öœ†²ãí =¦¤_éÃÐS²½ÎÙ©»ˆ „#/BMú¥~Ñ@.‡vÀÿѽ»3¤¾V®�G©PmØ ìBi¡uèyÈf È,S[?ð–^X1jðHo¬Oð1"ÝÝ�£Ìéó�_S fÍDl x‘­åËØ³d´ }¸©ë³Ã.ËàJ ý>ètÐ#“fÚ| Ã)=Kl�Á¯‚m¹ô(Ë5�IRdšÎPT†^ï*Þ@s™µΧ°Œ”Ù‹v4b‚ò:}]c�# Ã¬ìŸ×»å–wiž-D®y/½¹pYàÎçÓþܪ½à ¡uèyÈf È,S[?ð–^X1jðHo¬Oð…²ÿKÍzÍ/£{`b@÷pp”¹§5�'ióqÙ™…¼sØ©ñïL±Ua ·šÛ$º S»^€ZŒÉϹà›üN¥íEƒ™¢Å¹iŽ©‘­Šÿ�Ø1¨»;ì×ôËÄ¥¼ÆX@ÕaE{ý>xÇ8=¡ ÈE–nE”²€©düÚ\üØÉ~ÒWä°'ó^@�÷"©Ü7Y--;¨üµ/¿“fÚ| Ã)=Kl�Á¯‚m¹ô(Ë5�IRdšÎPT†^ßñáWªdEí߀xcá(l혧òÒyÊ~'Ýxx` êeÖC—hÒqæ. Ã}+aƒŽs[MDŸmÏô¡9ŒN‰³Ãª×€ qÁt!Ò³™N=í¼^·sWŸÎ´•õ°pŒ^µ‚&*Œ­Уúëê|©[Ìe@OµIîh½ö+>Š·Ø©ñïL±Ua ·šÛ$ºü‘ï³z‰ÑÛw &UÕÇÓ“è)S¶(—ÐS„S�ݯç ‡.ì£:~öœ†²„ä÷ ©7œÄJo¾§nXc¦÷™Øz»Öò·U"»è°MÑS²ÆJäUäã…°oq¡uèyÈf È,S[?ð–^X1jðHo¬OðëÛ°»Rל9;$¼ýÍò¯3Ñ‹ƒn„ð1Gd˜Wš¥ÿ.6ݵÏëqLZ@Ép¢ç{…¤×^n49è[µ·Öµ’Š|ŒÅÐ-Ë>2…V¢� Z™Íü÷KW;Ò®D²–/ KÝ�£Û¼·š�Cú[ìØEܱMX¾r‰zó †…:�)h—áäê`F©A/øEˆRQrx_8¹ž)ü8‹ZÔ+S­§R‹Q «|vŒHnŽU$v«(´1�} >F‰b qèô è3*Yé®:¦–ŸT¤Øæà£”§wÈle…£1Ô-õüiðu/ã×úŠ;pB§ñ;û×U DQ˜Dê¨þ؉î>JüèI4…¨ìv’¢7°o{ÀoQçr^€�¥Bõ‡À¯Ÿ‰%G-7ÖœCñÎ?íTX(Ñönz~h_>ÉÏ8W¤ :š} žÔ)C"ï¬äØùy"ÖüßáG¸Có |>èc¨À§Â”°¾Uo³Û©)Üô|A•5FÁÿ¡º»5t ¼¹æE ocþk&ê©x[ª³Ý}uÉ+­ˆ\¢g åëÕž‘(ÀµiŽ1‘‹~¹ÔÙuhñþ༱xv –8ïƒÈôú’_åƒM÷�k¡$]å¤T¬ÆeEI…eY�Á]-5ó�ïËw;GB;·„ fÙÌÁF+ k+{@’±_òñÇå¾Hr –—Å ¥_sŸ×²Y%0v²;º_bÆzZ¬`CGvH•q�ê¥d1/wN³vã@z¹Ý=æH’à˽ÄX=K‘ &; ]ësžë{êÉÏ8NÌÍU^oa-̪ä­*ÓØùy"ÖüßáG¸Có |�x‡óòÀÚ„uî$‰ui*)Üô|A•5FÁÿ¡º»5t L³µ†¸Ç›H~C2’.Ý.ôº,w"yLA«÷€8 L…k‹ÿi¢j©È…Û&öjm°ÙËûŽ*J·-¦R5\„³»0Ê4íT/n1¾­y…AÆùm«Ä™ãžž:ýAqáÕ#•†ƒàÛ­÷í} y¤ì§‘Z&ÇθÂöþ>lP#ñ¼Ãöô]Æa9F6ÝýDh:´_*I”N1l¦Š–˜·/ëÚÞ~’ÔµM¦Ý4F9¤„S¢[—¸oWÞè§{ÐjŸ„A=í‡tÚ ¤S~7'„erbCëC¨&"ýÈ-žt_ï>c‹S+)@.�‡sF�>¸šZòkFªjûgˆì¡æx¦¦½q]Íf4+«oˆÙ5èß7.`¸…'%¨œÁ•%[ beôþ±]Æa9F6ÝýDh:´_*nt"> */ 12: 13: namespace DataTables; 14: if (!defined('DATATABLES')) exit(); 15: 16: 17: /** 18: * Base class for DataTables classes. 19: */ 20: class Ext { 21: /** 22: * Static method to instantiate a new instance of a class. 23: * 24: * A factory method that will create a new instance of the class 25: * that has extended 'Ext'. This allows classes to be instantiated 26: * and then chained - which otherwise isn't available until PHP 5.4. 27: * If using PHP 5.4 or later, simply create a 'new' instance of the 28: * target class and chain methods as normal. 29: * @return \DataTables\Editor|\DataTables\Editor\Field|\DataTables\Editor\Join|\DataTables\Editor\Upload Instantiated class 30: * @static 31: */ 32: public static function instantiate () 33: { 34: $rc = new \ReflectionClass( get_called_class() ); 35: $args = func_get_args(); 36: 37: return count( $args ) === 0 ? 38: $rc->newInstance() : 39: $rc->newInstanceArgs( $args ); 40: } 41: 42: /** 43: * Static method to instantiate a new instance of a class (shorthand of 44: * 'instantiate'). 45: * 46: * This method performs exactly the same actions as the 'instantiate' 47: * static method, but is simply shorter and easier to type! 48: * @return \DataTables\Editor|\DataTables\Editor\Field|\DataTables\Editor\Join|\DataTables\Editor\Upload class 49: * @static 50: */ 51: public static function inst () 52: { 53: $rc = new \ReflectionClass( get_called_class() ); 54: $args = func_get_args(); 55: 56: return count( $args ) === 0 ? 57: $rc->newInstance() : 58: $rc->newInstanceArgs( $args ); 59: } 60: 61: /** 62: * Common getter / setter function for DataTables classes. 63: * 64: * This getter / setter method makes building getter / setting methods 65: * easier, by abstracting everything to a single function call. 66: * @param mixed &$prop The property to set 67: * @param mixed $val The value to set - if given as null, then we assume 68: * that the function is being used as a getter. 69: * @param boolean $array Treat the target property as an array or not 70: * (default false). If used as an array, then values passed in are added 71: * to the $prop array. 72: * @return self|mixed Class instance if setting (allowing chaining), or 73: * the value requested if getting. 74: */ 75: protected function _getSet( &$prop, $val, $array=false ) 76: { 77: // Get 78: if ( $val === null ) { 79: return $prop; 80: } 81: 82: // Set 83: if ( $array ) { 84: // Property is an array, merge or add to array 85: is_array( $val ) ? 86: $prop = array_merge( $prop, $val ) : 87: $prop[] = $val; 88: } 89: else { 90: // Property is just a value 91: $prop = $val; 92: } 93: 94: return $this; 95: } 96: 97: /** 98: * Determine if a property is available in a data set (allowing `null` to be 99: * a valid value) 100: * @param string $name Javascript dotted object name to write to 101: * @param array $data Data source array to read from 102: * @return boolean true if present, false otherwise 103: * @private 104: */ 105: protected function _propExists ( $name, $data ) 106: { 107: if ( strpos($name, '.') === false ) { 108: return isset( $data[ $name ] ); 109: } 110: 111: $names = explode( '.', $name ); 112: $inner = $data; 113: 114: for ( $i=0 ; $i<count($names)-1 ; $i++ ) { 115: if ( ! isset( $inner[ $names[$i] ] ) ) { 116: return false; 117: } 118: 119: $inner = $inner[ $names[$i] ]; 120: } 121: 122: if ( isset( $names[count($names)-1] ) ) { 123: $idx = $names[count($names)-1]; 124: 125: return isset( $inner[ $idx ] ); 126: } 127: 128: return false; 129: } 130: 131: /** 132: * Read a value from a data structure, using Javascript dotted object 133: * notation. This is the inverse of the `_writeProp` method and provides 134: * the same support, matching DataTables' ability to read nested JSON 135: * data objects. 136: * 137: * @param string $name Javascript dotted object name to write to 138: * @param array $data Data source array to read from 139: * @return mixed The read value, or null if no value found. 140: * @private 141: */ 142: protected function _readProp ( $name, $data ) 143: { 144: if ( strpos($name, '.') === false ) { 145: return isset( $data[ $name ] ) ? 146: $data[ $name ] : 147: null; 148: } 149: 150: $names = explode( '.', $name ); 151: $inner = $data; 152: 153: for ( $i=0 ; $i<count($names)-1 ; $i++ ) { 154: if ( ! isset( $inner[ $names[$i] ] ) ) { 155: return null; 156: } 157: 158: $inner = $inner[ $names[$i] ]; 159: } 160: 161: if ( isset( $names[count($names)-1] ) ) { 162: $idx = $names[count($names)-1]; 163: 164: return isset( $inner[ $idx ] ) ? 165: $inner[ $idx ] : 166: null; 167: } 168: 169: return null; 170: } 171: 172: /** 173: * Write the field's value to an array structure, using Javascript dotted 174: * object notation to indicate JSON data structure. For example `name.first` 175: * gives the data structure: `name: { first: ... }`. This matches DataTables 176: * own ability to do this on the client-side, although this doesn't 177: * implement implement quite such a complex structure (no array / function 178: * support). 179: * 180: * @param array &$out Array to write the data to 181: * @param string $name Javascript dotted object name to write to 182: * @param mixed $value Value to write 183: * @throws \Exception Information about duplicate properties 184: * @private 185: */ 186: protected function _writeProp( &$out, $name, $value ) 187: { 188: if ( strpos($name, '.') === false ) { 189: $out[ $name ] = $value; 190: return; 191: } 192: 193: $names = explode( '.', $name ); 194: $inner = &$out; 195: for ( $i=0 ; $i<count($names)-1 ; $i++ ) { 196: $loopName = $names[$i]; 197: 198: if ( ! isset( $inner[ $loopName ] ) ) { 199: $inner[ $loopName ] = array(); 200: } 201: else if ( ! is_array( $inner[ $loopName ] ) ) { 202: throw new \Exception( 203: 'A property with the name `'.$name.'` already exists. This '. 204: 'can occur if you have properties which share a prefix - '. 205: 'for example `name` and `name.first`.' 206: ); 207: } 208: 209: $inner = &$inner[ $loopName ]; 210: } 211: 212: if ( isset( $inner[ $names[count($names)-1] ] ) ) { 213: throw new \Exception( 214: 'Duplicate field detected - a field with the name `'.$name.'` '. 215: 'already exists.' 216: ); 217: } 218: 219: $inner[ $names[count($names)-1] ] = $value; 220: } 221: } 222: 223: