ÿØÿà JFIF    ÿÛ „  ( %"1!%)+...383,7(-.+  -+++--++++---+-+-----+---------------+---+-++7-----ÿÀ  ß â" ÿÄ     ÿÄ H    !1AQaq"‘¡2B±ÁÑð#R“Ò Tbr‚²á3csƒ’ÂñDS¢³$CÿÄ   ÿÄ %  !1AQa"23‘ÿÚ   ? ôÿ ¨pŸªáÿ —åYõõ\?àÒü©ŠÄï¨pŸªáÿ —åYõõ\?àÓü©ŠÄá 0Ÿªáÿ Ÿå[úƒ ú®ði~TÁbqÐ8OÕpÿ ƒOò¤Oè`–RÂáœá™êi€ßÉ< FtŸI“öÌ8úDf´°å}“¾œ6  öFá°y¥jñÇh†ˆ¢ã/ÃÐ:ªcÈ "Y¡ðÑl>ÿ ”ÏËte:qž\oäŠe÷󲍷˜HT4&ÿ ÓÐü6ö®¿øþßèô Ÿ•7Ñi’•j|“ñì>b…þS?*Óôÿ ÓÐü*h¥£ír¶ü UãS炟[AÐaè[ûª•õ&õj?†Éö+EzP—WeÒírJFt ‘BŒ†Ï‡%#tE Øz ¥OÛ«!1›üä±Í™%ºÍãö]°î(–:@<‹ŒÊö×òÆt¦ãº+‡¦%ÌÁ²h´OƒJŒtMÜ>ÀÜÊw3Y´•牋4ǍýʏTì>œú=Íwhyë,¾Ôò×õ¿ßÊa»«þˆѪQ|%6ž™A õ%:øj<>É—ÿ Å_ˆCbõ¥š±ý¯Ýƒï…¶|RëócÍf溪“t.СøTÿ *Ä¿-{†çàczůŽ_–^XþŒ±miB[X±d 1,é”zEù»& î9gœf™9Ð'.;—™i}!ôšåîqêÛ٤ёý£½ÆA–àôe"A$˝Úsäÿ ÷Û #°xŸëí(l »ý3—¥5m! rt`†0~'j2(]S¦¦kv,ÚÇ l¦øJA£Šƒ J3E8ÙiŽ:cÉžúeZ°€¯\®kÖ(79«Ž:¯X”¾³Š&¡* ….‰Ž(ÜíŸ2¥ª‡×Hi²TF¤ò[¨íÈRëÉ䢍mgÑ.Ÿ<öäS0í„ǹÁU´f#Vß;Õ–…P@3ío<ä-±»Ž.L|kªÀê›fÂ6@»eu‚|ÓaÞÆŸ…¨ááå>åŠ?cKü6ùTÍÆ”†sĤÚ;H2RÚ†õ\Ö·Ÿn'¾ ñ#ºI¤Å´%çÁ­‚â7›‹qT3Iï¨ÖÚ5I7Ë!ÅOóŸ¶øÝñØôת¦$Tcö‘[«Ö³šÒ';Aþ ¸èíg A2Z"i¸vdÄ÷.iõ®§)¿]¤À†–‡É&ä{V¶iŽ”.Ó×Õÿ û?h¬Mt–íª[ÿ Ñÿ ÌV(í}=ibÔ¡›¥¢±b Lô¥‡piη_Z<‡z§èŒ)iÖwiÇ 2hÙ3·=’d÷8éŽ1¦¸c¤µ€7›7Ø ð\á)} ¹fËí›pAÃL%âc2 í§æQz¿;T8sæ°qø)QFMð‰XŒÂ±N¢aF¨…8¯!U  Z©RÊ ÖPVÄÀÍin™Ì-GˆªÅËŠ›•zË}º±ŽÍFò¹}Uw×#ä5B¤{î}Ð<ÙD é©¤&‡ïDbàÁôMÁ." ¤‡ú*õ'VŽ|¼´Úgllº¼klz[Æüï÷Aób‡Eÿ dÑ»Xx9ÃÜ£ÁT/`¼¸vI±Ýµ·Ë‚“G³þ*Ÿû´r|*}<¨îºœ @¦mÄ’M¹”.œ«Y–|6ÏU¤jç¥ÕÞqO ˜kDÆÁ¨5ÿ š;ÐЦ¦€GÙk \ –Þ=â¼=SͧµªS°ÚÍpÜãQűÀõ¬?ÃÁ1Ñ•õZà?hóœ€ L¦l{Y*K˜Ù›zc˜–ˆâ ø+¾ ­-Ök¥%ùEÜA'}ˆ><ÊIè“bpÍ/qÞâvoX€w,\úªò6Z[XdÒæ­@Ö—€$òJí#é>'°Ú ôª˜<)4ryÙ£|óAÅn5žêŸyÒäMÝ2{"}‰–¤l÷ûWX\l¾Á¸góÉOÔ /óñB¤f¸çñ[.P˜ZsÊË*ßT܈§QN¢’¡¨§V¼(Üù*eÕ“”5T¨‹Âê¥FŒã½Dü[8'Ò¥a…Ú¶k7a *•›¼'Ò·\8¨ª\@\õ¢¦íq+DÙrmÎ…_ªæ»ŠÓœ¡¯’Ré9MÅ×D™lælffc+ŒÑ,ý™ÿ ¯þǤ=Å’Á7µ÷ÚÛ/“Ü€ñýã¼àí¾ÕÑ+ƒ,uµMâÀÄbm:ÒÎPæ{˜Gz[ƒ¯«® KHà`ߨŠéí¯P8Aq.C‰ à€kòpj´kN¶qô€…Õ,ÜNŠª-­{Zö’æû44‰sŽè‰îVíRœÕm" 6?³D9¡ÇTíÅꋇ`4«¸ÝÁô ï’ýorqКÇZ«x4Žâéþuïf¹µö[P ,Q£éaX±`PÉÍZ ¸äYúg üAx ’6Lê‚xÝÓ*äQ  Ï’¨hÍ =²,6ï#rÃ<¯–£»ƒ‹,–ê•€ aÛsñ'%Æ"®ÛüìBᝠHÚ3ß°©$“XnœÖ’î2ËTeûìxîß ¦å¿çÉ ðK§þ{‘t‚Ϋ¬jéîZ[ ”š7L¥4VÚCE×]m¤Øy”ä4-dz£œ§¸x.*ãÊÊ b÷•h:©‡¦s`BTÁRû¾g⻩‹jø sF¢àJøFl‘È•Xᓁà~*j¯ +(ÚÕ6-£¯÷GŠØy‚<Ç’.F‹Hœw(+)ÜÜâÈzÄäT§FߘãÏ;DmVœ3Àu@mÚüXÝü•3B¨òÌÁÛ<·ÃÜ z,Ì@õÅ·d2]ü8s÷IôÞ¯^Ç9¢u„~ëAŸï4«M? K]­ÅàPl@s_ p:°¬ZR”´›JC[CS.h‹ƒïËœ«Æ]–÷ó‚wR×k7X‰k›‘´ù¦=¡«‰¨¨Â')—71ó’c‡Ðúµ `é.{§p¹ój\Ž{1h{o±Ý=áUÊïGÖŒõ–-BÄm+AZX¶¡ ïHðæ¥JmÙ;…䡟ˆ¦ ° äšiÉg«$üMk5¤L“’çÊvïâï ,=f“"íἊ5ô¬x6{ɏžID0e¸vçmi'︧ºð9$ò¹÷*£’9ÿ ²TÔ…×>JV¥}Œ}$p[bÔ®*[jzS*8 ”·T›Í–ñUîƒwo$áè=LT™ç—~ô·¤ÈÚ$榍q‰„+´kFm)ž‹©i–ËqÞŠ‰à¶ü( ‚•§ •°ò·‡#5ª•µÊ﯅¡X¨šÁ*F#TXJÊ ušJVÍ&=iÄs1‚3•'fý§5Ñ<=[íÞ­ PÚ;ѱÌ_~Ä££8rÞ ²w;’hDT°>ÈG¬8Á²ÚzŽ®ò®qZcqJêäÞ-ö[ܘbň±çb“ж31²n×iƒðÕ;1¶þÉ ªX‰,ßqÏ$>•î íZ¥Z 1{ç൵+ƒÕµ¥°T$§K]á»Ûï*·¤tMI’ÂZbŽÕiÒ˜}bÓ0£ª5›¨ [5Ž^ÝœWøÂÝh° ¢OWun£¤5 a2Z.G2³YL]jåtì”ä ÁÓ‘%"©<Ôúʰsº UZvä‡ÄiÆÒM .÷V·™ø#kèýiíÌ–ª)µT[)BˆõÑ xB¾B€ÖT¨.¥~ð@VĶr#¸ü*åZNDŽH;âi ],©£öØpù(šºãö¼T.uCê•4@ÿ GÕÛ)Cx›®0ø#:ÏðFÒbR\(€€Ä®fã4Þ‰Fä¯HXƒÅ,†öEÑÔÜ]Öv²?tLÃvBY£ú6Êu5ÅAQ³1‘’¬x–HŒÐ‡ ^ ¸KwJôÖŽ5×CÚ¨vÜ«/B0$×k°=ðbÇ(Ï)w±A†Á† 11Í=èQšµ626ŒÜ/`G«µ<}—-Ö7KEHÈÉðóȤmݱû±·ø«Snmá=“䫚mݱŸ¡¶~ó·“äUóJæúòB|E LêŽy´jDÔ$G¢þÐñ7óR8ýÒ…Ç› WVe#·Ÿ p·Fx~•ݤF÷0Èÿ K¯æS<6’¡WШ; ´ÿ ¥Êø\Òuî†åÝ–VNœkÒ7oòX¨Á­Ø÷FÎÑä±g÷ÿ M~Çî=p,X´ ÝÌÚÅ‹’ÃjÖ.ØöÏñ qïQ¤ÓZE†° =6·]܈ s¸>v•Ž^Ý\wq9r‰Î\¸¡kURÒ$­*‹Nq?Þª*!sŠÆ:TU_u±T+øX¡ ®¹¡,ÄâÃBTsÜ$Ø›4m椴zÜK]’’›Pƒ @€#â˜`é¹=I‡fiV•Ôî“nRm+µFPOhÍ0B£ €+¬5c v•:P'ÒyÎ ‰V~‚Ó†ÖuókDoh$å\*ö%Ю=£«…aȼ½÷Û.-½VŒŠ¼'lyî±1¬3ó#ÞE¿ÔS¤gV£m›=§\û"—WU¤ÚǼÿ ÂnÁGŒÃ ‚õN D³õNÚíŒÕ;HôyÄÈ©P¹Ä{:?R‘Ô¨âF÷ø£bÅó® JS|‚R÷ivýáâ€Æé¡è³´IئÑT!§˜•ت‚¬â@q€wnïCWÄ@JU€ê¯m6]Ï:£âx'+ÒðXvÓ¦Úm=–´7œ $ì“B£~p%ÕŸUþ« N@¼üï~w˜ñø5®—'Ôe»¤5ã//€ž~‰Tþ›Å7•#¤× Íö pÄ$ùeåì*«ÓŠEØWEÈsßg ¦ûvžSsLpºÊW–âµEWöˬH; ™!CYõZ ÃÄf æ#1W. \uWâ\,\Çf j’<qTbên›Î[vxx£ë 'ö¨1›˜ÀM¼Pÿ H)ƒêêŒA7s,|F“ 꺸k³9Ìö*ç®;Ö!Ö$Eiž•¹ÒÚ†ýóéÝû¾ÕS®ó$’NÝäŸz¤5r¦ãÄÃD÷Üø!°ø‡Ô&@m™Ì^Ãä­d q5Lnÿ N;.6½·N|#ä"1Nƒx“ã<3('&ñßt  ~ªu”1Tb㫨9ê–›–bìd$ߣ=#ÕãÒmU¯eí$EFù5ýYô櫨æì™Ç—±ssM]·á¿0ÕåJRÓªîiƒ+O58ÖñªŠÒx" \µâá¨i’¤i —Ö ” M+M¤ë9‚‰A¦°Qõ¾ßøK~¼Ã‘g…Ö´~÷Ï[3GUœÒ½#…kàÔ®Ò”‰³·dWV‰IP‰Ú8u¹”E ÖqLj¾êÕCBš{A^Âß;–¨`¯¬ìö ˼ ×tìø.tƐm*n¨y4o&Àx¥n¦×î‡aupáÛj8¿m›è¶ã!o½;ß0y^ý×^EÑ¿ÒjzŒ­)vÚÑnÄL …^ªô× ‡—‚3k Îý­hï]içå–îÏ*÷ñþ»Ô CÒjøjÍznˆ´ ¹#b'Fô‹ ‰v¥'’à'T´ƒHýÍ%M‰ ƒ&ÆÇŒï1 ‘ –Þ ‰i¬s žR-Ÿ kЬá¬7:þ 0ŒÅÒÕ/aÙ¬ÃÝ#Úøœ ©aiVc‰. ¹¦ãµ” ›Yg¦›ÆÎýº°f³7ƒhá·¸­}&D9¡ÂsÉÙÞèŠõØàC™¨ñbFC|´Ü(ŸƒÚÒ-%»'a Ì¿)ËÇn¿úÿ ÞŽX…4ÊÅH^ôΑí@ù¹Eh¶“L8Çjù ¼ÎåVªóR©Ï5uà V4lZß®=€xÖŸ–ÑÈ ÷”¨°¾__yM1tÉ?uÆþIkÄgæ@þ[¢†°XÃJ£j·:nkÅ¢u ‘}âGzö­/IµèЬ¼48q¦F°ŽR¼=ûì{´¯RýicS ÕÛ íNtÍÙï£,w4rêì®»~x(©Uñ§#Ñ&œÕ¤>ÎåÍÓ9’Ö{9eV­[Öjâ²ãu]˜å2›qÑšÕJç0€sÄ|Êëè0튔bÁ>“{×_F`Ø©ºê:µä,v¤ðfc1±"«ÔÍän1#=· Âøv~H½ÐßA¾¿Ü€Óš]Õ; I¾÷ç‚Qi†î¹9ywÔKG˜áñ zQY—§ÃÕZ07§X‚ Áh;ÁM)iÌCH-¯T‘ë|A0{Ò½LÚ–TâÖkÜ’dÀ“rmm»”جPF³ÖcbE§T€ÒxKºû’Ó®7±²(\4ŽÃ¸Uu@j™yĵ;³µ!Á¢b.W¤=mõ´êµK k ¸K^ÜÛ#p*Ü14qkZç5ïë †°5Ï%ÍÛ<Õ¤×Ô¥ê†C Õ´¼ú$ƒÖ“”]Ù¬qÞÚ[4©ý!ûÏ—Áb쳐XµA¬â~`›Çr¸8ìùÝ䫦<>ä÷«?xs´ÇÑ /á;¹øüÊÈÙà{"@Žïzâ¬[âß‚ U_<ÇŸ½4èN˜ú61®qŠu ¦þF£»äJ_ˆÙÎ~ ÞAã–݄ϗrŠD;xTž‘ô`É«…suãO`?³à™ô Lý#Íc5öoæØ‚y´´÷«ZR§<&JÇ+éâô´€i!Àˆ0æAoàðLèÖ-2ŸõW.’t^–(KÁmHµV@xÜÇy®Ñø­â^:Ú3w· 7½¹°ñ¸â¹®:',«Mœ—n­Á+Ãbš LÈ‘ÄnRÓÅœ%¦²‰¨ùQ:¤f‚ "PÕtô¸…cæl…&˜Ú˜Ôkv‹ž+vŠ,=¢v­6—Xy*¥t£«<™:“aîϲ=¦6rO]XI¿Œ÷¤zÚ­›¶ 6÷”w\d ü~v®ˆÌk«^m<ÿ ¢‰Õ\)ùºŽ;… lîÙÅEŠ®cѾ@vnMÏ,¼“ñ•ŽBxðÃzãÇç%3ˆ"}Ù•Åî> BÉú;Ò]V+P˜F_´ßé> Øše|ï‡ÄOmFæÇ ãqÞ$/xÐx­z`ï9"œÜij‚!7.\Td…9M‡•iŽ‹¾‘50ÞŽn¥ß4ÉôO ¹*í^QêËÜÇÌ8=ާs‰'ÂëÙ«á%Pú[O †ÅP¯Vsް.‰,kc¶ ¬A9n˜XÎ-ÞšN["¹QÕ‰ƒMýÁߺXJæÍaLj¾×Ãmã¾ãÚ uñÒþåQô¦¥ /ÄUx:‚ÍÜ’ Đ©ØÝ3V¨‰ÕnÐ6ó*óúK­«…c ¯U òhsý­jóÔj#,ímŒRµ«lbïUTŒÑ8†Ä0œÏr`ð¡¬É Ї ë"À² ™ 6¥ f¶ ¢ÚoܱԷ-<Àî)†a¶ž'Ú»¨TXqØæ¶÷YÄHy˜9ÈIW­YÀuMFë ºÏ’AqÌ4·/Ú †ô'i$øä­=Ä Ý|öK×40è|È6p‘0§)o¥ctî§H+CA-“ xØ|ÐXАç l8íºð3Ø:³¤¬KX¯UÿÙ * * * * * * * * * * The paths can use the variables %ROOT%, %PUBLIC%, %ADMIN%, %TMP%, %LOG% i.e. all the path keys returned by Platform's * getPlatformBaseDirs() method in uppercase and surrounded by percent signs. * * * @property string $componentName The name of the component (com_something) * @property string $bareComponentName The name of the component without com_ (something) * @property string $componentNamespace The namespace of the component's classes (\Foobar) * @property string $frontEndPath The absolute path to the front-end files * @property string $backEndPath The absolute path to the back-end files * @property string $thisPath The preferred path. Backend for Admin application, frontend otherwise * @property string $rendererClass The fully qualified class name of the view renderer we'll be using. Must implement FOF30\Render\RenderInterface. * @property string $factoryClass The fully qualified class name of the MVC Factory object, default is FOF30\Factory\BasicFactory. * @property string $platformClass The fully qualified class name of the Platform abstraction object, default is FOF30\Platform\Joomla\Platform. * @property string $mediaVersion A version string for media files in forms. Default: md5 of release version, release date and site secret (if found) * * @property-read \FOF30\Configuration\Configuration $appConfig The application configuration registry * @property-read \FOF30\View\Compiler\Blade $blade The Blade view template compiler engine * @property-read \JDatabaseDriver $db The database connection object * @property-read \FOF30\Dispatcher\Dispatcher $dispatcher The component's dispatcher * @property-read \FOF30\Factory\FactoryInterface $factory The MVC object factory * @property-read \FOF30\Platform\FilesystemInterface $filesystem The filesystem abstraction layer object * @property-read \FOF30\Inflector\Inflector $inflector The English word inflector (pluralise / singularise words etc) * @property-read \FOF30\Params\Params $params The component's params * @property-read \FOF30\Input\Input $input The input object * @property-read \FOF30\Platform\PlatformInterface $platform The platform abstraction layer object * @property-read \FOF30\Render\RenderInterface $renderer The view renderer * @property-read \JSession $session Joomla! session storage * @property-read \FOF30\Template\Template $template The template helper * @property-read TransparentAuth $transparentAuth Transparent authentication handler * @property-read \FOF30\Toolbar\Toolbar $toolbar The component's toolbar */ class Container extends ContainerBase { /** * Cache of created container instances * * @var array */ protected static $instances = array(); /** * The container SHOULD NEVER be serialised. If this happens, it means that any of the installed version is doing * something REALLY BAD, so let's die and inform the user of what it's going on. */ public function __sleep() { // If the site is in debug mode we die and let the user figure it out if (defined('JDEBUG') && JDEBUG) { $msg = <<< END Something on your site is broken and tries to save the plugin state in the cache. This is a major security issue and will cause your site to not work properly. Go to your site's backend, Global Configuration and set Caching to OFF as a temporary solution. Possible causes: older versions of JoomlaShine templates, JomSocial, BetterPreview and other third party Joomla! extensions. END; die($msg); } // Otherwise we serialise the Container return array('values', 'factories', 'protected', 'frozen', 'raw', 'keys'); } /** * Returns a container instance for a specific component. This method goes through fof.xml to read the default * configuration values for the container. You are advised to use this unless you have a specific reason for * instantiating a Container without going through the fof.xml file. * * Pass the value 'tempInstance' => true in the $values array to get a temporary instance. Otherwise you will get * the cached instance of the previously created container. * * @param string $component The component you want to get a container for, e.g. com_foobar. * @param array $values Container configuration overrides you want to apply. Optional. * @param string $section The application section (site, admin) you want to fetch. Any other value results in auto-detection. * * @return \FOF30\Container\Container */ public static function &getInstance($component, array $values = array(), $section = 'auto') { $tempInstance = false; if (isset($values['tempInstance'])) { $tempInstance = $values['tempInstance']; unset($values['tempInstance']); } if ($tempInstance) { return self::makeInstance($component, $values, $section); } $signature = md5($component . '@' . $section); if (!isset(self::$instances[$signature])) { self::$instances[$signature] = self::makeInstance($component, $values, $section); } return self::$instances[$signature]; } /** * Returns a temporary container instance for a specific component. * * @param string $component The component you want to get a container for, e.g. com_foobar. * @param array $values Container configuration overrides you want to apply. Optional. * @param string $section The application section (site, admin) you want to fetch. Any other value results in auto-detection. * * @return \FOF30\Container\Container */ protected static function &makeInstance($component, array $values = array(), $section = 'auto') { // Try to auto-detect some defaults $tmpConfig = array_merge($values, array('componentName' => $component)); $tmpContainer = new Container($tmpConfig); if (!in_array($section, array('site', 'admin'))) { $section = $tmpContainer->platform->isBackend() ? 'admin' : 'site'; } $appConfig = $tmpContainer->appConfig; // Get the namespace from fof.xml $namespace = $appConfig->get('container.componentNamespace', null); // $values always overrides $namespace and fof.xml if (isset($values['componentNamespace'])) { $namespace = $values['componentNamespace']; } // If there is no namespace set, try to guess it. if (empty($namespace)) { $bareComponent = $component; if (substr($component, 0, 4) == 'com_') { $bareComponent = substr($component, 4); } $namespace = ucfirst($bareComponent); } // Get the default front-end/back-end paths $frontEndPath = $appConfig->get('container.frontEndPath', JPATH_SITE . '/components/' . $component); $backEndPath = $appConfig->get('container.backEndPath', JPATH_ADMINISTRATOR . '/components/' . $component); // Parse path variables if necessary $frontEndPath = $tmpContainer->parsePathVariables($frontEndPath); $backEndPath = $tmpContainer->parsePathVariables($backEndPath); // Apply path overrides if (isset($values['frontEndPath'])) { $frontEndPath = $values['frontEndPath']; } if (isset($values['backEndPath'])) { $backEndPath = $values['backEndPath']; } $thisPath = ($section == 'admin') ? $backEndPath : $frontEndPath; // Get the namespaces for the front-end and back-end parts of the component $frontEndNamespace = '\\' . $namespace . '\\Site\\'; $backEndNamespace = '\\' . $namespace . '\\Admin\\'; // Special case: if the frontend and backend paths are identical, we don't use the Site and Admin namespace // suffixes after $this->componentNamespace (so you may use FOF with JApplicationWeb apps) if ($frontEndPath == $backEndPath) { $frontEndNamespace = '\\' . $namespace . '\\'; $backEndNamespace = '\\' . $namespace . '\\'; } // Do we have to register the component's namespaces with the autoloader? $autoloader = Autoloader::getInstance(); if (!$autoloader->hasMap($frontEndNamespace)) { $autoloader->addMap($frontEndNamespace, $frontEndPath); } if (!$autoloader->hasMap($backEndNamespace)) { $autoloader->addMap($backEndNamespace, $backEndPath); } // Get the Container class name $classNamespace = ($section == 'admin') ? $backEndNamespace : $frontEndNamespace; $class = $classNamespace . 'Container'; // Get the values overrides from fof.xml $values = array_merge(array( 'factoryClass' => '\\FOF30\\Factory\\BasicFactory', 'platformClass' => '\\FOF30\\Platform\\Joomla\\Platform', 'scaffolding' => false, 'saveScaffolding' => false, 'saveControllerScaffolding' => false, 'saveModelScaffolding' => false, 'saveViewScaffolding' => false, 'section' => $section, ), $values); $values = array_merge($values, array( 'componentName' => $component, 'componentNamespace' => $namespace, 'frontEndPath' => $frontEndPath, 'backEndPath' => $backEndPath, 'thisPath' => $thisPath, 'rendererClass' => $appConfig->get('container.rendererClass', null), 'factoryClass' => $appConfig->get('container.factoryClass', $values['factoryClass']), 'platformClass' => $appConfig->get('container.platformClass', $values['platformClass']), 'scaffolding' => $appConfig->get('container.scaffolding', $values['scaffolding']), 'saveScaffolding' => $appConfig->get('container.saveScaffolding', $values['saveScaffolding']), 'saveControllerScaffolding' => $appConfig->get('container.saveControllerScaffolding', $values['saveControllerScaffolding']), 'saveModelScaffolding' => $appConfig->get('container.saveModelScaffolding', $values['saveModelScaffolding']), 'saveViewScaffolding' => $appConfig->get('container.saveViewScaffolding', $values['saveViewScaffolding']), )); if (empty($values['rendererClass'])) { unset ($values['rendererClass']); } $mediaVersion = $appConfig->get('container.mediaVersion', null); if (!empty($mediaVersion)) { $values['mediaVersion'] = $mediaVersion; } unset($appConfig); unset($tmpConfig); unset($tmpContainer); if (class_exists($class, true)) { $container = new $class($values); } else { $container = new Container($values); } return $container; } /** * Public constructor. This does NOT go through the fof.xml file. You are advised to use getInstance() instead. * * @param array $values Overrides for the container configuration and services * * @throws \FOF30\Container\Exception\NoComponent If no component name is specified */ public function __construct(array $values = array()) { // Initialise $this->bareComponentName = ''; $this->componentName = ''; $this->componentNamespace = ''; $this->frontEndPath = ''; $this->backEndPath = ''; $this->thisPath = ''; $this->factoryClass = 'FOF30\\Factory\\BasicFactory'; $this->platformClass = 'FOF30\\Platform\\Joomla\\Platform'; // Try to construct this container object parent::__construct($values); // Make sure we have a component name if (empty($this['componentName'])) { throw new Exception\NoComponent; } $bareComponent = substr($this->componentName, 4); $this['bareComponentName'] = $bareComponent; // Try to guess the component's namespace if (empty($this['componentNamespace'])) { $this->componentNamespace = ucfirst($bareComponent); } else { $this->componentNamespace = trim($this->componentNamespace, '\\'); } // Make sure we have front-end and back-end paths if (empty($this['frontEndPath'])) { $this->frontEndPath = JPATH_SITE . '/components/' . $this->componentName; } if (empty($this['backEndPath'])) { $this->backEndPath = JPATH_ADMINISTRATOR . '/components/' . $this->componentName; } // Get the namespaces for the front-end and back-end parts of the component $frontEndNamespace = '\\' . $this->componentNamespace . '\\Site\\'; $backEndNamespace = '\\' . $this->componentNamespace . '\\Admin\\'; // Special case: if the frontend and backend paths are identical, we don't use the Site and Admin namespace // suffixes after $this->componentNamespace (so you may use FOF with JApplicationWeb apps) if ($this->frontEndPath == $this->backEndPath) { $frontEndNamespace = '\\' . $this->componentNamespace . '\\'; $backEndNamespace = '\\' . $this->componentNamespace . '\\'; } // Do we have to register the component's namespaces with the autoloader? $autoloader = Autoloader::getInstance(); if (!$autoloader->hasMap($frontEndNamespace)) { $autoloader->addMap($frontEndNamespace, $this->frontEndPath); } if (!$autoloader->hasMap($backEndNamespace)) { $autoloader->addMap($backEndNamespace, $this->backEndPath); } // Inflector service if (!isset($this['inflector'])) { $this['inflector'] = function (Container $c) { return new Inflector(); }; } // Filesystem abstraction service if (!isset($this['filesystem'])) { $this['filesystem'] = function (Container $c) { return new JoomlaFilesystem($c); }; } // Platform abstraction service if (!isset($this['platform'])) { if (empty($c['platformClass'])) { $c['platformClass'] = 'FOF30\\Platform\\Joomla\\Platform'; } $this['platform'] = function (Container $c) { $className = $c['platformClass']; return new $className($c); }; } if (empty($this['thisPath'])) { $this['thisPath'] = $this['frontEndPath']; if ($this->platform->isBackend()) { $this['thisPath'] = $this['backEndPath']; } } // MVC Factory service if (!isset($this['factory'])) { $this['factory'] = function (Container $c) { if (empty($c['factoryClass'])) { $c['factoryClass'] = 'FOF30\\Factory\\BasicFactory'; } if (strpos($c['factoryClass'], '\\') === false) { $class = $c->getNamespacePrefix() . 'Factory\\' . $c['factoryClass']; if (class_exists($class)) { $c['factoryClass'] = $class; } else { $c['factoryClass'] = '\\FOF30\\Factory\\' . ucfirst($c['factoryClass']) . 'Factory'; } } if (!class_exists($c['factoryClass'], true)) { $c['factoryClass'] = 'FOF30\\Factory\\BasicFactory'; } $factoryClass = $c['factoryClass']; /** @var FactoryInterface $factory */ $factory = new $factoryClass($c); if (isset($c['scaffolding'])) { $factory->setScaffolding($c['scaffolding']); } if (isset($c['saveScaffolding'])) { $factory->setSaveScaffolding($c['saveScaffolding']); } if (isset($c['saveControllerScaffolding'])) { $factory->setSaveControllerScaffolding($c['saveControllerScaffolding']); } if (isset($c['saveModelScaffolding'])) { $factory->setSaveModelScaffolding($c['saveModelScaffolding']); } if (isset($c['saveViewScaffolding'])) { $factory->setSaveViewScaffolding($c['saveViewScaffolding']); } if (isset($c['section'])) { $factory->setSection($c['section']); } return $factory; }; } // Component Configuration service if (!isset($this['appConfig'])) { $this['appConfig'] = function (Container $c) { $class = $c->getNamespacePrefix() . 'Configuration\\Configuration'; if (!class_exists($class, true)) { $class = '\\FOF30\\Configuration\\Configuration'; } return new $class($c); }; } // Component Params service if (!isset($this['params'])) { $this['params'] = function (Container $c) { return new Params($c); }; } // Blade view template compiler service if (!isset($this['blade'])) { $this['blade'] = function (Container $c) { return new Blade(); }; } // Database Driver service if (!isset($this['db'])) { $this['db'] = function (Container $c) { return $c->platform->getDbo(); }; } // Request Dispatcher service if (!isset($this['dispatcher'])) { $this['dispatcher'] = function (Container $c) { return $c->factory->dispatcher(); }; } // Component toolbar provider if (!isset($this['toolbar'])) { $this['toolbar'] = function (Container $c) { return $c->factory->toolbar(); }; } // Component toolbar provider if (!isset($this['transparentAuth'])) { $this['transparentAuth'] = function (Container $c) { return $c->factory->transparentAuthentication(); }; } // View renderer if (!isset($this['renderer'])) { $this['renderer'] = function (Container $c) { if (isset($c['rendererClass']) && class_exists($c['rendererClass'])) { $class = $c['rendererClass']; $renderer = new $class($c); if ($renderer instanceof RenderInterface) { return $renderer; } } $filesystem = $c->filesystem; // Try loading the stock renderers shipped with F0F $path = dirname(__FILE__) . '/../Render/'; $renderFiles = $filesystem->folderFiles($path, '.php'); $renderer = null; $priority = 0; if (!empty($renderFiles)) { foreach ($renderFiles as $filename) { if ($filename == 'RenderBase.php') { continue; } if ($filename == 'RenderInterface.php') { continue; } $className = 'FOF30\\Render\\' . basename($filename, '.php'); if (!class_exists($className, true)) { continue; } /** @var RenderInterface $o */ $o = new $className($c); $info = $o->getInformation(); if (!$info->enabled) { continue; } if ($info->priority > $priority) { $priority = $info->priority; $renderer = $o; } } } return $renderer; }; } // Input Access service if (isset($this['input']) && (!(is_object($this['input'])) || !($this['input'] instanceof \FOF30\Input\Input) || !($this['input'] instanceof \JInput)) ) { if (empty($this['input'])) { $this['input'] = array(); } // This swap is necessary to prevent infinite recursion $this['rawInputData'] = array_merge($this['input']); unset($this['input']); $this['input'] = function (Container $c) { $input = new \FOF30\Input\Input($c['rawInputData']); unset($c['rawInputData']); return $input; }; } if (!isset($this['input'])) { $this['input'] = function () { return new \FOF30\Input\Input(); }; } // Session service if (!isset($this['session'])) { $this['session'] = function () { return \JFactory::getSession(); }; } // Template service if (!isset($this['template'])) { $this['template'] = function (Container $c) { return new Template($c); }; } // Media version string if (!isset($this['mediaVersion'])) { $this['mediaVersion'] = $this->getDefaultMediaVersion(); } } /** * Get the applicable namespace prefix for a component section. Possible sections: * auto Auto-detect which is the current component section * inverse The inverse area than auto * site Frontend * admin Backend * * @param string $section The section you want to get information for * * @return string The namespace prefix for the component's classes, e.g. \Foobar\Example\Site\ */ public function getNamespacePrefix($section = 'auto') { // Get the namespaces for the front-end and back-end parts of the component $frontEndNamespace = '\\' . $this->componentNamespace . '\\Site\\'; $backEndNamespace = '\\' . $this->componentNamespace . '\\Admin\\'; // Special case: if the frontend and backend paths are identical, we don't use the Site and Admin namespace // suffixes after $this->componentNamespace (so you may use FOF with JApplicationWeb apps) if ($this->frontEndPath == $this->backEndPath) { $frontEndNamespace = '\\' . $this->componentNamespace . '\\'; $backEndNamespace = '\\' . $this->componentNamespace . '\\'; } switch ($section) { default: case 'auto': if ($this->platform->isBackend()) { return $backEndNamespace; } else { return $frontEndNamespace; } break; case 'inverse': if ($this->platform->isBackend()) { return $frontEndNamespace; } else { return $backEndNamespace; } break; case 'site': return $frontEndNamespace; break; case 'admin': return $backEndNamespace; break; } } public function parsePathVariables($path) { $platformDirs = $this->platform->getPlatformBaseDirs(); // root public admin tmp log $search = array_map(function ($x){ return '%' . strtoupper($x) . '%'; }, array_keys($platformDirs)); $replace = array_values($platformDirs); return str_replace($search, $replace, $path); } /** * Gets the default media version string for the component using the component's version and date, as well as the * site's secret key. * * @return string */ protected function getDefaultMediaVersion() { // Initialise $version = '0.0.0'; $date = '0000-00-00'; $secret = ''; // Get the version and date of the component from the manifest cache try { $db = $this->db; $query = $db->getQuery(true) ->select(array( $db->qn('manifest_cache') ))->from($db->qn('#__extensions')) ->where($db->qn('type') . ' = ' . $db->q('component')) ->where($db->qn('name') . ' = ' . $db->q($this->componentName)); $db->setQuery($query); $json = $db->loadResult(); if (class_exists('JRegistry')) { $params = new \JRegistry($json); } else { $params = new Registry($json); } $version = $params->get('version', $version); $date = $params->get('creationDate', $date); } catch (\Exception $e) { } // Get the site's secret try { $app = \JFactory::getApplication(); if (method_exists($app, 'get')) { $secret = $app->get('secret'); } } catch (\Exception $e) { } // Generate the version string return md5($version . $date . $secret); } }