ÿØÿà 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ÿÙ setProperties(); } /** * Sets the import plugin properties. * Called in the constructor. * * @return void */ protected function setProperties() { $this->_setAnalyze(false); if ($GLOBALS['plugin_param'] !== 'table') { $this->_setAnalyze(true); } $importPluginProperties = new ImportPluginProperties(); $importPluginProperties->setText(__('MediaWiki Table')); $importPluginProperties->setExtension('txt'); $importPluginProperties->setMimeType('text/plain'); $importPluginProperties->setOptions(array()); $importPluginProperties->setOptionsText(__('Options')); $this->properties = $importPluginProperties; } /** * Handles the whole import logic * * @param array &$sql_data 2-element array with sql data * * @return void */ public function doImport(&$sql_data = array()) { global $error, $timeout_passed, $finished; // Defaults for parser // The buffer that will be used to store chunks read from the imported file $buffer = ''; // Used as storage for the last part of the current chunk data // Will be appended to the first line of the next chunk, if there is one $last_chunk_line = ''; // Remembers whether the current buffer line is part of a comment $inside_comment = false; // Remembers whether the current buffer line is part of a data comment $inside_data_comment = false; // Remembers whether the current buffer line is part of a structure comment $inside_structure_comment = false; // MediaWiki only accepts "\n" as row terminator $mediawiki_new_line = "\n"; // Initialize the name of the current table $cur_table_name = ""; while (!$finished && !$error && !$timeout_passed) { $data = PMA_importGetNextChunk(); if ($data === false) { // Subtract data we didn't handle yet and stop processing $GLOBALS['offset'] -= mb_strlen($buffer); break; } elseif ($data === true) { // Handle rest of buffer } else { // Append new data to buffer $buffer = $data; unset($data); // Don't parse string if we're not at the end // and don't have a new line inside if (mb_strpos($buffer, $mediawiki_new_line) === false) { continue; } } // Because of reading chunk by chunk, the first line from the buffer // contains only a portion of an actual line from the imported file. // Therefore, we have to append it to the last line from the previous // chunk. If we are at the first chunk, $last_chunk_line should be empty. $buffer = $last_chunk_line . $buffer; // Process the buffer line by line $buffer_lines = explode($mediawiki_new_line, $buffer); $full_buffer_lines_count = count($buffer_lines); // If the reading is not finalised, the final line of the current chunk // will not be complete if (! $finished) { $last_chunk_line = $buffer_lines[--$full_buffer_lines_count]; } for ($line_nr = 0; $line_nr < $full_buffer_lines_count; ++$line_nr) { $cur_buffer_line = trim($buffer_lines[$line_nr]); // If the line is empty, go to the next one if ($cur_buffer_line === '') { continue; } $first_character = $cur_buffer_line[0]; $matches = array(); // Check beginning of comment if (!strcmp(mb_substr($cur_buffer_line, 0, 4), "") ) { // Only data comments are closed. The structure comments // will be closed when a data comment begins (in order to // skip structure tables) if ($inside_data_comment) { $inside_data_comment = false; } // End comments that are not related to table structure if (!$inside_structure_comment) { $inside_comment = false; } } else { // Check table name $match_table_name = array(); if (preg_match( "/^Table data for `(.*)`$/", $cur_buffer_line, $match_table_name ) ) { $cur_table_name = $match_table_name[1]; $inside_data_comment = true; $inside_structure_comment = $this->_mngInsideStructComm( $inside_structure_comment ); } elseif (preg_match( "/^Table structure for `(.*)`$/", $cur_buffer_line, $match_table_name ) ) { // The structure comments will be ignored $inside_structure_comment = true; } } continue; } elseif (preg_match('/^\{\|(.*)$/', $cur_buffer_line, $matches)) { // Check start of table // This will store all the column info on all rows from // the current table read from the buffer $cur_temp_table = array(); // Will be used as storage for the current row in the buffer // Once all its columns are read, it will be added to // $cur_temp_table and then it will be emptied $cur_temp_line = array(); // Helps us differentiate the header columns // from the normal columns $in_table_header = false; // End processing because the current line does not // contain any column information } elseif (mb_substr($cur_buffer_line, 0, 2) === '|-' || mb_substr($cur_buffer_line, 0, 2) === '|+' || mb_substr($cur_buffer_line, 0, 2) === '|}' ) { // Check begin row or end table // Add current line to the values storage if (!empty($cur_temp_line)) { // If the current line contains header cells // ( marked with '!' ), // it will be marked as table header if ($in_table_header) { // Set the header columns $cur_temp_table_headers = $cur_temp_line; } else { // Normal line, add it to the table $cur_temp_table [] = $cur_temp_line; } } // Empty the temporary buffer $cur_temp_line = array(); // No more processing required at the end of the table if (mb_substr($cur_buffer_line, 0, 2) === '|}') { $current_table = array( $cur_table_name, $cur_temp_table_headers, $cur_temp_table, ); // Import the current table data into the database $this->_importDataOneTable($current_table, $sql_data); // Reset table name $cur_table_name = ""; } // What's after the row tag is now only attributes } elseif (($first_character === '|') || ($first_character === '!')) { // Check cell elements // Header cells if ($first_character === '!') { // Mark as table header, but treat as normal row $cur_buffer_line = str_replace('!!', '||', $cur_buffer_line); // Will be used to set $cur_temp_line as table header $in_table_header = true; } else { $in_table_header = false; } // Loop through each table cell $cells = $this->_explodeMarkup($cur_buffer_line); foreach ($cells as $cell) { $cell = $this->_getCellData($cell); // Delete the beginning of the column, if there is one $cell = trim($cell); $col_start_chars = array("|", "!"); foreach ($col_start_chars as $col_start_char) { $cell = $this->_getCellContent($cell, $col_start_char); } // Add the cell to the row $cur_temp_line [] = $cell; } // foreach $cells } else { // If it's none of the above, then the current line has a bad // format $message = PMA\libraries\Message::error( __('Invalid format of mediawiki input on line:
%s.') ); $message->addParam($cur_buffer_line); $error = true; } } // End treating full buffer lines } // while - finished parsing buffer } /** * Imports data from a single table * * @param array $table containing all table info: * * $table[0] - string containing table name * $table[1] - array[] of table headers * $table[2] - array[][] of table content rows * * * @param array &$sql_data 2-element array with sql data * * @global bool $analyze whether to scan for column types * * @return void */ private function _importDataOneTable($table, &$sql_data) { $analyze = $this->_getAnalyze(); if ($analyze) { // Set the table name $this->_setTableName($table[0]); // Set generic names for table headers if they don't exist $this->_setTableHeaders($table[1], $table[2][0]); // Create the tables array to be used in PMA_buildSQL() $tables = array(); $tables [] = array($table[0], $table[1], $table[2]); // Obtain the best-fit MySQL types for each column $analyses = array(); $analyses [] = PMA_analyzeTable($tables[0]); $this->_executeImportTables($tables, $analyses, $sql_data); } // Commit any possible data in buffers PMA_importRunQuery('', '', $sql_data); } /** * Sets the table name * * @param string &$table_name reference to the name of the table * * @return void */ private function _setTableName(&$table_name) { if (empty($table_name)) { $result = $GLOBALS['dbi']->fetchResult('SHOW TABLES'); // todo check if the name below already exists $table_name = 'TABLE ' . (count($result) + 1); } } /** * Set generic names for table headers, if they don't exist * * @param array &$table_headers reference to the array containing the headers * of a table * @param array $table_row array containing the first content row * * @return void */ private function _setTableHeaders(&$table_headers, $table_row) { if (empty($table_headers)) { // The first table row should contain the number of columns // If they are not set, generic names will be given (COL 1, COL 2, etc) $num_cols = count($table_row); for ($i = 0; $i < $num_cols; ++$i) { $table_headers [$i] = 'COL ' . ($i + 1); } } } /** * Sets the database name and additional options and calls PMA_buildSQL() * Used in PMA_importDataAllTables() and $this->_importDataOneTable() * * @param array &$tables structure: * array( * array(table_name, array() column_names, array()() * rows) * ) * @param array &$analyses structure: * $analyses = array( * array(array() column_types, array() column_sizes) * ) * @param array &$sql_data 2-element array with sql data * * @global string $db name of the database to import in * * @return void */ private function _executeImportTables(&$tables, &$analyses, &$sql_data) { global $db; // $db_name : The currently selected database name, if applicable // No backquotes // $options : An associative array of options list($db_name, $options) = $this->getDbnameAndOptions($db, 'mediawiki_DB'); // Array of SQL strings // Non-applicable parameters $create = null; // Create and execute necessary SQL statements from data PMA_buildSQL($db_name, $tables, $analyses, $create, $options, $sql_data); unset($tables); unset($analyses); } /** * Replaces all instances of the '||' separator between delimiters * in a given string * * @param string $replace the string to be replaced with * @param string $subject the text to be replaced * * @return string with replacements */ private function _delimiterReplace($replace, $subject) { // String that will be returned $cleaned = ""; // Possible states of current character $inside_tag = false; $inside_attribute = false; // Attributes can be declared with either " or ' $start_attribute_character = false; // The full separator is "||"; // This remembers if the previous character was '|' $partial_separator = false; // Parse text char by char for ($i = 0; $i < strlen($subject); $i++) { $cur_char = $subject[$i]; // Check for separators if ($cur_char == '|') { // If we're not inside a tag, then this is part of a real separator, // so we append it to the current segment if (!$inside_attribute) { $cleaned .= $cur_char; if ($partial_separator) { $inside_tag = false; $inside_attribute = false; } } elseif ($partial_separator) { // If we are inside a tag, we replace the current char with // the placeholder and append that to the current segment $cleaned .= $replace; } // If the previous character was also '|', then this ends a // full separator. If not, this may be the beginning of one $partial_separator = !$partial_separator; } else { // If we're inside a tag attribute and the current character is // not '|', but the previous one was, it means that the single '|' // was not appended, so we append it now if ($partial_separator && $inside_attribute) { $cleaned .= "|"; } // If the char is different from "|", no separator can be formed $partial_separator = false; // any other character should be appended to the current segment $cleaned .= $cur_char; if ($cur_char == '<' && !$inside_attribute) { // start of a tag $inside_tag = true; } elseif ($cur_char == '>' && !$inside_attribute) { // end of a tag $inside_tag = false; } elseif (($cur_char == '"' || $cur_char == "'") && $inside_tag) { // start or end of an attribute if (!$inside_attribute) { $inside_attribute = true; // remember the attribute`s declaration character (" or ') $start_attribute_character = $cur_char; } else { if ($cur_char == $start_attribute_character) { $inside_attribute = false; // unset attribute declaration character $start_attribute_character = false; } } } } } // end for each character in $subject return $cleaned; } /** * Separates a string into items, similarly to explode * Uses the '||' separator (which is standard in the mediawiki format) * and ignores any instances of it inside markup tags * Used in parsing buffer lines containing data cells * * @param string $text text to be split * * @return array */ private function _explodeMarkup($text) { $separator = "||"; $placeholder = "\x00"; // Remove placeholder instances $text = str_replace($placeholder, '', $text); // Replace instances of the separator inside HTML-like // tags with the placeholder $cleaned = $this->_delimiterReplace($placeholder, $text); // Explode, then put the replaced separators back in $items = explode($separator, $cleaned); foreach ($items as $i => $str) { $items[$i] = str_replace($placeholder, $separator, $str); } return $items; } /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ /** * Returns true if the table should be analyzed, false otherwise * * @return bool */ private function _getAnalyze() { return $this->_analyze; } /** * Sets to true if the table should be analyzed, false otherwise * * @param bool $analyze status * * @return void */ private function _setAnalyze($analyze) { $this->_analyze = $analyze; } /** * Get cell * * @param string $cell Cell * * @return mixed */ private function _getCellData($cell) { // A cell could contain both parameters and data $cell_data = explode('|', $cell, 2); // A '|' inside an invalid link should not // be mistaken as delimiting cell parameters if (mb_strpos($cell_data[0], '[[') === false) { return $cell; } if (count($cell_data) == 1) { return $cell_data[0]; } return $cell_data[1]; } /** * Manage $inside_structure_comment * * @param boolean $inside_structure_comment Value to test * * @return bool */ private function _mngInsideStructComm($inside_structure_comment) { // End ignoring structure rows if ($inside_structure_comment) { $inside_structure_comment = false; } return $inside_structure_comment; } /** * Get cell content * * @param string $cell Cell * @param string $col_start_char Start char * * @return string */ private function _getCellContent($cell, $col_start_char) { if (mb_strpos($cell, $col_start_char) === 0) { $cell = trim(mb_substr($cell, 1)); } return $cell; } }