12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582 |
- <?php
- /**
- * Yii bootstrap file.
- *
- * This file is automatically generated using 'build lite' command.
- * It is the result of merging commonly used Yii class files with
- * comments and trace statements removed away.
- *
- * By using this file instead of yii.php, an Yii application may
- * improve performance due to the reduction of PHP parsing time.
- * The performance improvement is especially obvious when PHP APC extension
- * is enabled.
- *
- * DO NOT modify this file manually.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @link http://www.yiiframework.com/
- * @copyright 2008-2013 Yii Software LLC
- * @license http://www.yiiframework.com/license/
- * @version $Id: $
- * @since 1.0
- */
- defined('YII_BEGIN_TIME') or define('YII_BEGIN_TIME',microtime(true));
- defined('YII_DEBUG') or define('YII_DEBUG',false);
- defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',0);
- defined('YII_ENABLE_EXCEPTION_HANDLER') or define('YII_ENABLE_EXCEPTION_HANDLER',true);
- defined('YII_ENABLE_ERROR_HANDLER') or define('YII_ENABLE_ERROR_HANDLER',true);
- defined('YII_PATH') or define('YII_PATH',dirname(__FILE__));
- defined('YII_ZII_PATH') or define('YII_ZII_PATH',YII_PATH.DIRECTORY_SEPARATOR.'zii');
- class YiiBase
- {
- public static $classMap=array();
- public static $enableIncludePath=true;
- private static $_aliases=array('system'=>YII_PATH,'zii'=>YII_ZII_PATH); // alias => path
- private static $_imports=array(); // alias => class name or directory
- private static $_includePaths; // list of include paths
- private static $_app;
- private static $_logger;
- public static function getVersion()
- {
- return '1.1.16';
- }
- public static function createWebApplication($config=null)
- {
- return self::createApplication('CWebApplication',$config);
- }
- public static function createConsoleApplication($config=null)
- {
- return self::createApplication('CConsoleApplication',$config);
- }
- public static function createApplication($class,$config=null)
- {
- return new $class($config);
- }
- public static function app()
- {
- return self::$_app;
- }
- public static function setApplication($app)
- {
- if(self::$_app===null || $app===null)
- self::$_app=$app;
- else
- throw new CException(Yii::t('yii','Yii application can only be created once.'));
- }
- public static function getFrameworkPath()
- {
- return YII_PATH;
- }
- public static function createComponent($config)
- {
- if(is_string($config))
- {
- $type=$config;
- $config=array();
- }
- elseif(isset($config['class']))
- {
- $type=$config['class'];
- unset($config['class']);
- }
- else
- throw new CException(Yii::t('yii','Object configuration must be an array containing a "class" element.'));
- if(!class_exists($type,false))
- $type=Yii::import($type,true);
- if(($n=func_num_args())>1)
- {
- $args=func_get_args();
- if($n===2)
- $object=new $type($args[1]);
- elseif($n===3)
- $object=new $type($args[1],$args[2]);
- elseif($n===4)
- $object=new $type($args[1],$args[2],$args[3]);
- else
- {
- unset($args[0]);
- $class=new ReflectionClass($type);
- // Note: ReflectionClass::newInstanceArgs() is available for PHP 5.1.3+
- // $object=$class->newInstanceArgs($args);
- $object=call_user_func_array(array($class,'newInstance'),$args);
- }
- }
- else
- $object=new $type;
- foreach($config as $key=>$value)
- $object->$key=$value;
- return $object;
- }
- public static function import($alias,$forceInclude=false)
- {
- if(isset(self::$_imports[$alias])) // previously imported
- return self::$_imports[$alias];
- if(class_exists($alias,false) || interface_exists($alias,false))
- return self::$_imports[$alias]=$alias;
- if(($pos=strrpos($alias,'\\'))!==false) // a class name in PHP 5.3 namespace format
- {
- $namespace=str_replace('\\','.',ltrim(substr($alias,0,$pos),'\\'));
- if(($path=self::getPathOfAlias($namespace))!==false)
- {
- $classFile=$path.DIRECTORY_SEPARATOR.substr($alias,$pos+1).'.php';
- if($forceInclude)
- {
- if(is_file($classFile))
- require($classFile);
- else
- throw new CException(Yii::t('yii','Alias "{alias}" is invalid. Make sure it points to an existing PHP file and the file is readable.',array('{alias}'=>$alias)));
- self::$_imports[$alias]=$alias;
- }
- else
- self::$classMap[$alias]=$classFile;
- return $alias;
- }
- else
- {
- // try to autoload the class with an autoloader
- if (class_exists($alias,true))
- return self::$_imports[$alias]=$alias;
- else
- throw new CException(Yii::t('yii','Alias "{alias}" is invalid. Make sure it points to an existing directory or file.',
- array('{alias}'=>$namespace)));
- }
- }
- if(($pos=strrpos($alias,'.'))===false) // a simple class name
- {
- // try to autoload the class with an autoloader if $forceInclude is true
- if($forceInclude && (Yii::autoload($alias,true) || class_exists($alias,true)))
- self::$_imports[$alias]=$alias;
- return $alias;
- }
- $className=(string)substr($alias,$pos+1);
- $isClass=$className!=='*';
- if($isClass && (class_exists($className,false) || interface_exists($className,false)))
- return self::$_imports[$alias]=$className;
- if(($path=self::getPathOfAlias($alias))!==false)
- {
- if($isClass)
- {
- if($forceInclude)
- {
- if(is_file($path.'.php'))
- require($path.'.php');
- else
- throw new CException(Yii::t('yii','Alias "{alias}" is invalid. Make sure it points to an existing PHP file and the file is readable.',array('{alias}'=>$alias)));
- self::$_imports[$alias]=$className;
- }
- else
- self::$classMap[$className]=$path.'.php';
- return $className;
- }
- else // a directory
- {
- if(self::$_includePaths===null)
- {
- self::$_includePaths=array_unique(explode(PATH_SEPARATOR,get_include_path()));
- if(($pos=array_search('.',self::$_includePaths,true))!==false)
- unset(self::$_includePaths[$pos]);
- }
- array_unshift(self::$_includePaths,$path);
- if(self::$enableIncludePath && set_include_path('.'.PATH_SEPARATOR.implode(PATH_SEPARATOR,self::$_includePaths))===false)
- self::$enableIncludePath=false;
- return self::$_imports[$alias]=$path;
- }
- }
- else
- throw new CException(Yii::t('yii','Alias "{alias}" is invalid. Make sure it points to an existing directory or file.',
- array('{alias}'=>$alias)));
- }
- public static function getPathOfAlias($alias)
- {
- if(isset(self::$_aliases[$alias]))
- return self::$_aliases[$alias];
- elseif(($pos=strpos($alias,'.'))!==false)
- {
- $rootAlias=substr($alias,0,$pos);
- if(isset(self::$_aliases[$rootAlias]))
- return self::$_aliases[$alias]=rtrim(self::$_aliases[$rootAlias].DIRECTORY_SEPARATOR.str_replace('.',DIRECTORY_SEPARATOR,substr($alias,$pos+1)),'*'.DIRECTORY_SEPARATOR);
- elseif(self::$_app instanceof CWebApplication)
- {
- if(self::$_app->findModule($rootAlias)!==null)
- return self::getPathOfAlias($alias);
- }
- }
- return false;
- }
- public static function setPathOfAlias($alias,$path)
- {
- if(empty($path))
- unset(self::$_aliases[$alias]);
- else
- self::$_aliases[$alias]=rtrim($path,'\\/');
- }
- public static function autoload($className,$classMapOnly=false)
- {
- // use include so that the error PHP file may appear
- if(isset(self::$classMap[$className]))
- include(self::$classMap[$className]);
- elseif(isset(self::$_coreClasses[$className]))
- include(YII_PATH.self::$_coreClasses[$className]);
- elseif($classMapOnly)
- return false;
- else
- {
- // include class file relying on include_path
- if(strpos($className,'\\')===false) // class without namespace
- {
- if(self::$enableIncludePath===false)
- {
- foreach(self::$_includePaths as $path)
- {
- $classFile=$path.DIRECTORY_SEPARATOR.$className.'.php';
- if(is_file($classFile))
- {
- include($classFile);
- if(YII_DEBUG && basename(realpath($classFile))!==$className.'.php')
- throw new CException(Yii::t('yii','Class name "{class}" does not match class file "{file}".', array(
- '{class}'=>$className,
- '{file}'=>$classFile,
- )));
- break;
- }
- }
- }
- else
- include($className.'.php');
- }
- else // class name with namespace in PHP 5.3
- {
- $namespace=str_replace('\\','.',ltrim($className,'\\'));
- if(($path=self::getPathOfAlias($namespace))!==false)
- include($path.'.php');
- else
- return false;
- }
- return class_exists($className,false) || interface_exists($className,false);
- }
- return true;
- }
- public static function trace($msg,$category='application')
- {
- if(YII_DEBUG)
- self::log($msg,CLogger::LEVEL_TRACE,$category);
- }
- public static function log($msg,$level=CLogger::LEVEL_INFO,$category='application')
- {
- if(self::$_logger===null)
- self::$_logger=new CLogger;
- if(YII_DEBUG && YII_TRACE_LEVEL>0 && $level!==CLogger::LEVEL_PROFILE)
- {
- $traces=debug_backtrace();
- $count=0;
- foreach($traces as $trace)
- {
- if(isset($trace['file'],$trace['line']) && strpos($trace['file'],YII_PATH)!==0)
- {
- $msg.="\nin ".$trace['file'].' ('.$trace['line'].')';
- if(++$count>=YII_TRACE_LEVEL)
- break;
- }
- }
- }
- self::$_logger->log($msg,$level,$category);
- }
- public static function beginProfile($token,$category='application')
- {
- self::log('begin:'.$token,CLogger::LEVEL_PROFILE,$category);
- }
- public static function endProfile($token,$category='application')
- {
- self::log('end:'.$token,CLogger::LEVEL_PROFILE,$category);
- }
- public static function getLogger()
- {
- if(self::$_logger!==null)
- return self::$_logger;
- else
- return self::$_logger=new CLogger;
- }
- public static function setLogger($logger)
- {
- self::$_logger=$logger;
- }
- public static function powered()
- {
- return Yii::t('yii','Powered by {yii}.', array('{yii}'=>'<a href="http://www.yiiframework.com/" rel="external">Yii Framework</a>'));
- }
- public static function t($category,$message,$params=array(),$source=null,$language=null)
- {
- if(self::$_app!==null)
- {
- if($source===null)
- $source=($category==='yii'||$category==='zii')?'coreMessages':'messages';
- if(($source=self::$_app->getComponent($source))!==null)
- $message=$source->translate($category,$message,$language);
- }
- if($params===array())
- return $message;
- if(!is_array($params))
- $params=array($params);
- if(isset($params[0])) // number choice
- {
- if(strpos($message,'|')!==false)
- {
- if(strpos($message,'#')===false)
- {
- $chunks=explode('|',$message);
- $expressions=self::$_app->getLocale($language)->getPluralRules();
- if($n=min(count($chunks),count($expressions)))
- {
- for($i=0;$i<$n;$i++)
- $chunks[$i]=$expressions[$i].'#'.$chunks[$i];
- $message=implode('|',$chunks);
- }
- }
- $message=CChoiceFormat::format($message,$params[0]);
- }
- if(!isset($params['{n}']))
- $params['{n}']=$params[0];
- unset($params[0]);
- }
- return $params!==array() ? strtr($message,$params) : $message;
- }
- public static function registerAutoloader($callback, $append=false)
- {
- if($append)
- {
- self::$enableIncludePath=false;
- spl_autoload_register($callback);
- }
- else
- {
- spl_autoload_unregister(array('YiiBase','autoload'));
- spl_autoload_register($callback);
- spl_autoload_register(array('YiiBase','autoload'));
- }
- }
- private static $_coreClasses=array(
- 'CApplication' => '/base/CApplication.php',
- 'CApplicationComponent' => '/base/CApplicationComponent.php',
- 'CBehavior' => '/base/CBehavior.php',
- 'CComponent' => '/base/CComponent.php',
- 'CErrorEvent' => '/base/CErrorEvent.php',
- 'CErrorHandler' => '/base/CErrorHandler.php',
- 'CException' => '/base/CException.php',
- 'CExceptionEvent' => '/base/CExceptionEvent.php',
- 'CHttpException' => '/base/CHttpException.php',
- 'CModel' => '/base/CModel.php',
- 'CModelBehavior' => '/base/CModelBehavior.php',
- 'CModelEvent' => '/base/CModelEvent.php',
- 'CModule' => '/base/CModule.php',
- 'CSecurityManager' => '/base/CSecurityManager.php',
- 'CStatePersister' => '/base/CStatePersister.php',
- 'CApcCache' => '/caching/CApcCache.php',
- 'CCache' => '/caching/CCache.php',
- 'CDbCache' => '/caching/CDbCache.php',
- 'CDummyCache' => '/caching/CDummyCache.php',
- 'CEAcceleratorCache' => '/caching/CEAcceleratorCache.php',
- 'CFileCache' => '/caching/CFileCache.php',
- 'CMemCache' => '/caching/CMemCache.php',
- 'CRedisCache' => '/caching/CRedisCache.php',
- 'CWinCache' => '/caching/CWinCache.php',
- 'CXCache' => '/caching/CXCache.php',
- 'CZendDataCache' => '/caching/CZendDataCache.php',
- 'CCacheDependency' => '/caching/dependencies/CCacheDependency.php',
- 'CChainedCacheDependency' => '/caching/dependencies/CChainedCacheDependency.php',
- 'CDbCacheDependency' => '/caching/dependencies/CDbCacheDependency.php',
- 'CDirectoryCacheDependency' => '/caching/dependencies/CDirectoryCacheDependency.php',
- 'CExpressionDependency' => '/caching/dependencies/CExpressionDependency.php',
- 'CFileCacheDependency' => '/caching/dependencies/CFileCacheDependency.php',
- 'CGlobalStateCacheDependency' => '/caching/dependencies/CGlobalStateCacheDependency.php',
- 'CAttributeCollection' => '/collections/CAttributeCollection.php',
- 'CConfiguration' => '/collections/CConfiguration.php',
- 'CList' => '/collections/CList.php',
- 'CListIterator' => '/collections/CListIterator.php',
- 'CMap' => '/collections/CMap.php',
- 'CMapIterator' => '/collections/CMapIterator.php',
- 'CQueue' => '/collections/CQueue.php',
- 'CQueueIterator' => '/collections/CQueueIterator.php',
- 'CStack' => '/collections/CStack.php',
- 'CStackIterator' => '/collections/CStackIterator.php',
- 'CTypedList' => '/collections/CTypedList.php',
- 'CTypedMap' => '/collections/CTypedMap.php',
- 'CConsoleApplication' => '/console/CConsoleApplication.php',
- 'CConsoleCommand' => '/console/CConsoleCommand.php',
- 'CConsoleCommandBehavior' => '/console/CConsoleCommandBehavior.php',
- 'CConsoleCommandEvent' => '/console/CConsoleCommandEvent.php',
- 'CConsoleCommandRunner' => '/console/CConsoleCommandRunner.php',
- 'CHelpCommand' => '/console/CHelpCommand.php',
- 'CDbCommand' => '/db/CDbCommand.php',
- 'CDbConnection' => '/db/CDbConnection.php',
- 'CDbDataReader' => '/db/CDbDataReader.php',
- 'CDbException' => '/db/CDbException.php',
- 'CDbMigration' => '/db/CDbMigration.php',
- 'CDbTransaction' => '/db/CDbTransaction.php',
- 'CActiveFinder' => '/db/ar/CActiveFinder.php',
- 'CActiveRecord' => '/db/ar/CActiveRecord.php',
- 'CActiveRecordBehavior' => '/db/ar/CActiveRecordBehavior.php',
- 'CDbColumnSchema' => '/db/schema/CDbColumnSchema.php',
- 'CDbCommandBuilder' => '/db/schema/CDbCommandBuilder.php',
- 'CDbCriteria' => '/db/schema/CDbCriteria.php',
- 'CDbExpression' => '/db/schema/CDbExpression.php',
- 'CDbSchema' => '/db/schema/CDbSchema.php',
- 'CDbTableSchema' => '/db/schema/CDbTableSchema.php',
- 'CCubridColumnSchema' => '/db/schema/cubrid/CCubridColumnSchema.php',
- 'CCubridSchema' => '/db/schema/cubrid/CCubridSchema.php',
- 'CCubridTableSchema' => '/db/schema/cubrid/CCubridTableSchema.php',
- 'CMssqlColumnSchema' => '/db/schema/mssql/CMssqlColumnSchema.php',
- 'CMssqlCommandBuilder' => '/db/schema/mssql/CMssqlCommandBuilder.php',
- 'CMssqlPdoAdapter' => '/db/schema/mssql/CMssqlPdoAdapter.php',
- 'CMssqlSchema' => '/db/schema/mssql/CMssqlSchema.php',
- 'CMssqlSqlsrvPdoAdapter' => '/db/schema/mssql/CMssqlSqlsrvPdoAdapter.php',
- 'CMssqlTableSchema' => '/db/schema/mssql/CMssqlTableSchema.php',
- 'CMysqlColumnSchema' => '/db/schema/mysql/CMysqlColumnSchema.php',
- 'CMysqlCommandBuilder' => '/db/schema/mysql/CMysqlCommandBuilder.php',
- 'CMysqlSchema' => '/db/schema/mysql/CMysqlSchema.php',
- 'CMysqlTableSchema' => '/db/schema/mysql/CMysqlTableSchema.php',
- 'COciColumnSchema' => '/db/schema/oci/COciColumnSchema.php',
- 'COciCommandBuilder' => '/db/schema/oci/COciCommandBuilder.php',
- 'COciSchema' => '/db/schema/oci/COciSchema.php',
- 'COciTableSchema' => '/db/schema/oci/COciTableSchema.php',
- 'CPgsqlColumnSchema' => '/db/schema/pgsql/CPgsqlColumnSchema.php',
- 'CPgsqlCommandBuilder' => '/db/schema/pgsql/CPgsqlCommandBuilder.php',
- 'CPgsqlSchema' => '/db/schema/pgsql/CPgsqlSchema.php',
- 'CPgsqlTableSchema' => '/db/schema/pgsql/CPgsqlTableSchema.php',
- 'CSqliteColumnSchema' => '/db/schema/sqlite/CSqliteColumnSchema.php',
- 'CSqliteCommandBuilder' => '/db/schema/sqlite/CSqliteCommandBuilder.php',
- 'CSqliteSchema' => '/db/schema/sqlite/CSqliteSchema.php',
- 'CChoiceFormat' => '/i18n/CChoiceFormat.php',
- 'CDateFormatter' => '/i18n/CDateFormatter.php',
- 'CDbMessageSource' => '/i18n/CDbMessageSource.php',
- 'CGettextMessageSource' => '/i18n/CGettextMessageSource.php',
- 'CLocale' => '/i18n/CLocale.php',
- 'CMessageSource' => '/i18n/CMessageSource.php',
- 'CNumberFormatter' => '/i18n/CNumberFormatter.php',
- 'CPhpMessageSource' => '/i18n/CPhpMessageSource.php',
- 'CGettextFile' => '/i18n/gettext/CGettextFile.php',
- 'CGettextMoFile' => '/i18n/gettext/CGettextMoFile.php',
- 'CGettextPoFile' => '/i18n/gettext/CGettextPoFile.php',
- 'CChainedLogFilter' => '/logging/CChainedLogFilter.php',
- 'CDbLogRoute' => '/logging/CDbLogRoute.php',
- 'CEmailLogRoute' => '/logging/CEmailLogRoute.php',
- 'CNoteLogRoute' => '/logging/CNoteLogRoute.php',
- 'CFileLogRoute' => '/logging/CFileLogRoute.php',
- 'CLogFilter' => '/logging/CLogFilter.php',
- 'CLogRoute' => '/logging/CLogRoute.php',
- 'CLogRouter' => '/logging/CLogRouter.php',
- 'CLogger' => '/logging/CLogger.php',
- 'CProfileLogRoute' => '/logging/CProfileLogRoute.php',
- 'CSysLogRoute' => '/logging/CSysLogRoute.php',
- 'CWebLogRoute' => '/logging/CWebLogRoute.php',
- 'CDateTimeParser' => '/utils/CDateTimeParser.php',
- 'CFileHelper' => '/utils/CFileHelper.php',
- 'CFormatter' => '/utils/CFormatter.php',
- 'CLocalizedFormatter' => '/utils/CLocalizedFormatter.php',
- 'CMarkdownParser' => '/utils/CMarkdownParser.php',
- 'CPasswordHelper' => '/utils/CPasswordHelper.php',
- 'CPropertyValue' => '/utils/CPropertyValue.php',
- 'CTimestamp' => '/utils/CTimestamp.php',
- 'CVarDumper' => '/utils/CVarDumper.php',
- 'CBooleanValidator' => '/validators/CBooleanValidator.php',
- 'CCaptchaValidator' => '/validators/CCaptchaValidator.php',
- 'CCompareValidator' => '/validators/CCompareValidator.php',
- 'CDateValidator' => '/validators/CDateValidator.php',
- 'CDefaultValueValidator' => '/validators/CDefaultValueValidator.php',
- 'CEmailValidator' => '/validators/CEmailValidator.php',
- 'CExistValidator' => '/validators/CExistValidator.php',
- 'CFileValidator' => '/validators/CFileValidator.php',
- 'CFilterValidator' => '/validators/CFilterValidator.php',
- 'CInlineValidator' => '/validators/CInlineValidator.php',
- 'CNumberValidator' => '/validators/CNumberValidator.php',
- 'CRangeValidator' => '/validators/CRangeValidator.php',
- 'CRegularExpressionValidator' => '/validators/CRegularExpressionValidator.php',
- 'CRequiredValidator' => '/validators/CRequiredValidator.php',
- 'CSafeValidator' => '/validators/CSafeValidator.php',
- 'CStringValidator' => '/validators/CStringValidator.php',
- 'CTypeValidator' => '/validators/CTypeValidator.php',
- 'CUniqueValidator' => '/validators/CUniqueValidator.php',
- 'CUnsafeValidator' => '/validators/CUnsafeValidator.php',
- 'CUrlValidator' => '/validators/CUrlValidator.php',
- 'CValidator' => '/validators/CValidator.php',
- 'CActiveDataProvider' => '/web/CActiveDataProvider.php',
- 'CArrayDataProvider' => '/web/CArrayDataProvider.php',
- 'CAssetManager' => '/web/CAssetManager.php',
- 'CBaseController' => '/web/CBaseController.php',
- 'CCacheHttpSession' => '/web/CCacheHttpSession.php',
- 'CClientScript' => '/web/CClientScript.php',
- 'CController' => '/web/CController.php',
- 'CDataProvider' => '/web/CDataProvider.php',
- 'CDataProviderIterator' => '/web/CDataProviderIterator.php',
- 'CDbHttpSession' => '/web/CDbHttpSession.php',
- 'CExtController' => '/web/CExtController.php',
- 'CFormModel' => '/web/CFormModel.php',
- 'CHttpCookie' => '/web/CHttpCookie.php',
- 'CHttpRequest' => '/web/CHttpRequest.php',
- 'CHttpSession' => '/web/CHttpSession.php',
- 'CHttpSessionIterator' => '/web/CHttpSessionIterator.php',
- 'COutputEvent' => '/web/COutputEvent.php',
- 'CPagination' => '/web/CPagination.php',
- 'CSort' => '/web/CSort.php',
- 'CSqlDataProvider' => '/web/CSqlDataProvider.php',
- 'CTheme' => '/web/CTheme.php',
- 'CThemeManager' => '/web/CThemeManager.php',
- 'CUploadedFile' => '/web/CUploadedFile.php',
- 'CUrlManager' => '/web/CUrlManager.php',
- 'CWebApplication' => '/web/CWebApplication.php',
- 'CWebModule' => '/web/CWebModule.php',
- 'CWidgetFactory' => '/web/CWidgetFactory.php',
- 'CAction' => '/web/actions/CAction.php',
- 'CInlineAction' => '/web/actions/CInlineAction.php',
- 'CViewAction' => '/web/actions/CViewAction.php',
- 'CAccessControlFilter' => '/web/auth/CAccessControlFilter.php',
- 'CAuthAssignment' => '/web/auth/CAuthAssignment.php',
- 'CAuthItem' => '/web/auth/CAuthItem.php',
- 'CAuthManager' => '/web/auth/CAuthManager.php',
- 'CBaseUserIdentity' => '/web/auth/CBaseUserIdentity.php',
- 'CDbAuthManager' => '/web/auth/CDbAuthManager.php',
- 'CPhpAuthManager' => '/web/auth/CPhpAuthManager.php',
- 'CUserIdentity' => '/web/auth/CUserIdentity.php',
- 'CWebUser' => '/web/auth/CWebUser.php',
- 'CFilter' => '/web/filters/CFilter.php',
- 'CFilterChain' => '/web/filters/CFilterChain.php',
- 'CHttpCacheFilter' => '/web/filters/CHttpCacheFilter.php',
- 'CInlineFilter' => '/web/filters/CInlineFilter.php',
- 'CForm' => '/web/form/CForm.php',
- 'CFormButtonElement' => '/web/form/CFormButtonElement.php',
- 'CFormElement' => '/web/form/CFormElement.php',
- 'CFormElementCollection' => '/web/form/CFormElementCollection.php',
- 'CFormInputElement' => '/web/form/CFormInputElement.php',
- 'CFormStringElement' => '/web/form/CFormStringElement.php',
- 'CGoogleApi' => '/web/helpers/CGoogleApi.php',
- 'CHtml' => '/web/helpers/CHtml.php',
- 'CJSON' => '/web/helpers/CJSON.php',
- 'CJavaScript' => '/web/helpers/CJavaScript.php',
- 'CJavaScriptExpression' => '/web/helpers/CJavaScriptExpression.php',
- 'CPradoViewRenderer' => '/web/renderers/CPradoViewRenderer.php',
- 'CViewRenderer' => '/web/renderers/CViewRenderer.php',
- 'CWebService' => '/web/services/CWebService.php',
- 'CWebServiceAction' => '/web/services/CWebServiceAction.php',
- 'CWsdlGenerator' => '/web/services/CWsdlGenerator.php',
- 'CActiveForm' => '/web/widgets/CActiveForm.php',
- 'CAutoComplete' => '/web/widgets/CAutoComplete.php',
- 'CClipWidget' => '/web/widgets/CClipWidget.php',
- 'CContentDecorator' => '/web/widgets/CContentDecorator.php',
- 'CFilterWidget' => '/web/widgets/CFilterWidget.php',
- 'CFlexWidget' => '/web/widgets/CFlexWidget.php',
- 'CHtmlPurifier' => '/web/widgets/CHtmlPurifier.php',
- 'CInputWidget' => '/web/widgets/CInputWidget.php',
- 'CMarkdown' => '/web/widgets/CMarkdown.php',
- 'CMaskedTextField' => '/web/widgets/CMaskedTextField.php',
- 'CMultiFileUpload' => '/web/widgets/CMultiFileUpload.php',
- 'COutputCache' => '/web/widgets/COutputCache.php',
- 'COutputProcessor' => '/web/widgets/COutputProcessor.php',
- 'CStarRating' => '/web/widgets/CStarRating.php',
- 'CTabView' => '/web/widgets/CTabView.php',
- 'CTextHighlighter' => '/web/widgets/CTextHighlighter.php',
- 'CTreeView' => '/web/widgets/CTreeView.php',
- 'CWidget' => '/web/widgets/CWidget.php',
- 'CCaptcha' => '/web/widgets/captcha/CCaptcha.php',
- 'CCaptchaAction' => '/web/widgets/captcha/CCaptchaAction.php',
- 'CBasePager' => '/web/widgets/pagers/CBasePager.php',
- 'CLinkPager' => '/web/widgets/pagers/CLinkPager.php',
- 'CListPager' => '/web/widgets/pagers/CListPager.php',
- );
- }
- spl_autoload_register(array('YiiBase','autoload'));
- class Yii extends YiiBase
- {
- }
- class CComponent
- {
- private $_e;
- private $_m;
- public function __get($name)
- {
- $getter='get'.$name;
- if(method_exists($this,$getter))
- return $this->$getter();
- elseif(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
- {
- // duplicating getEventHandlers() here for performance
- $name=strtolower($name);
- if(!isset($this->_e[$name]))
- $this->_e[$name]=new CList;
- return $this->_e[$name];
- }
- elseif(isset($this->_m[$name]))
- return $this->_m[$name];
- elseif(is_array($this->_m))
- {
- foreach($this->_m as $object)
- {
- if($object->getEnabled() && (property_exists($object,$name) || $object->canGetProperty($name)))
- return $object->$name;
- }
- }
- throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',
- array('{class}'=>get_class($this), '{property}'=>$name)));
- }
- public function __set($name,$value)
- {
- $setter='set'.$name;
- if(method_exists($this,$setter))
- return $this->$setter($value);
- elseif(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
- {
- // duplicating getEventHandlers() here for performance
- $name=strtolower($name);
- if(!isset($this->_e[$name]))
- $this->_e[$name]=new CList;
- return $this->_e[$name]->add($value);
- }
- elseif(is_array($this->_m))
- {
- foreach($this->_m as $object)
- {
- if($object->getEnabled() && (property_exists($object,$name) || $object->canSetProperty($name)))
- return $object->$name=$value;
- }
- }
- if(method_exists($this,'get'.$name))
- throw new CException(Yii::t('yii','Property "{class}.{property}" is read only.',
- array('{class}'=>get_class($this), '{property}'=>$name)));
- else
- throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',
- array('{class}'=>get_class($this), '{property}'=>$name)));
- }
- public function __isset($name)
- {
- $getter='get'.$name;
- if(method_exists($this,$getter))
- return $this->$getter()!==null;
- elseif(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
- {
- $name=strtolower($name);
- return isset($this->_e[$name]) && $this->_e[$name]->getCount();
- }
- elseif(is_array($this->_m))
- {
- if(isset($this->_m[$name]))
- return true;
- foreach($this->_m as $object)
- {
- if($object->getEnabled() && (property_exists($object,$name) || $object->canGetProperty($name)))
- return $object->$name!==null;
- }
- }
- return false;
- }
- public function __unset($name)
- {
- $setter='set'.$name;
- if(method_exists($this,$setter))
- $this->$setter(null);
- elseif(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
- unset($this->_e[strtolower($name)]);
- elseif(is_array($this->_m))
- {
- if(isset($this->_m[$name]))
- $this->detachBehavior($name);
- else
- {
- foreach($this->_m as $object)
- {
- if($object->getEnabled())
- {
- if(property_exists($object,$name))
- return $object->$name=null;
- elseif($object->canSetProperty($name))
- return $object->$setter(null);
- }
- }
- }
- }
- elseif(method_exists($this,'get'.$name))
- throw new CException(Yii::t('yii','Property "{class}.{property}" is read only.',
- array('{class}'=>get_class($this), '{property}'=>$name)));
- }
- public function __call($name,$parameters)
- {
- if($this->_m!==null)
- {
- foreach($this->_m as $object)
- {
- if($object->getEnabled() && method_exists($object,$name))
- return call_user_func_array(array($object,$name),$parameters);
- }
- }
- if(class_exists('Closure', false) && ($this->canGetProperty($name) || property_exists($this, $name)) && $this->$name instanceof Closure)
- return call_user_func_array($this->$name, $parameters);
- throw new CException(Yii::t('yii','{class} and its behaviors do not have a method or closure named "{name}".',
- array('{class}'=>get_class($this), '{name}'=>$name)));
- }
- public function asa($behavior)
- {
- return isset($this->_m[$behavior]) ? $this->_m[$behavior] : null;
- }
- public function attachBehaviors($behaviors)
- {
- foreach($behaviors as $name=>$behavior)
- $this->attachBehavior($name,$behavior);
- }
- public function detachBehaviors()
- {
- if($this->_m!==null)
- {
- foreach($this->_m as $name=>$behavior)
- $this->detachBehavior($name);
- $this->_m=null;
- }
- }
- public function attachBehavior($name,$behavior)
- {
- if(!($behavior instanceof IBehavior))
- $behavior=Yii::createComponent($behavior);
- $behavior->setEnabled(true);
- $behavior->attach($this);
- return $this->_m[$name]=$behavior;
- }
- public function detachBehavior($name)
- {
- if(isset($this->_m[$name]))
- {
- $this->_m[$name]->detach($this);
- $behavior=$this->_m[$name];
- unset($this->_m[$name]);
- return $behavior;
- }
- }
- public function enableBehaviors()
- {
- if($this->_m!==null)
- {
- foreach($this->_m as $behavior)
- $behavior->setEnabled(true);
- }
- }
- public function disableBehaviors()
- {
- if($this->_m!==null)
- {
- foreach($this->_m as $behavior)
- $behavior->setEnabled(false);
- }
- }
- public function enableBehavior($name)
- {
- if(isset($this->_m[$name]))
- $this->_m[$name]->setEnabled(true);
- }
- public function disableBehavior($name)
- {
- if(isset($this->_m[$name]))
- $this->_m[$name]->setEnabled(false);
- }
- public function hasProperty($name)
- {
- return method_exists($this,'get'.$name) || method_exists($this,'set'.$name);
- }
- public function canGetProperty($name)
- {
- return method_exists($this,'get'.$name);
- }
- public function canSetProperty($name)
- {
- return method_exists($this,'set'.$name);
- }
- public function hasEvent($name)
- {
- return !strncasecmp($name,'on',2) && method_exists($this,$name);
- }
- public function hasEventHandler($name)
- {
- $name=strtolower($name);
- return isset($this->_e[$name]) && $this->_e[$name]->getCount()>0;
- }
- public function getEventHandlers($name)
- {
- if($this->hasEvent($name))
- {
- $name=strtolower($name);
- if(!isset($this->_e[$name]))
- $this->_e[$name]=new CList;
- return $this->_e[$name];
- }
- else
- throw new CException(Yii::t('yii','Event "{class}.{event}" is not defined.',
- array('{class}'=>get_class($this), '{event}'=>$name)));
- }
- public function attachEventHandler($name,$handler)
- {
- $this->getEventHandlers($name)->add($handler);
- }
- public function detachEventHandler($name,$handler)
- {
- if($this->hasEventHandler($name))
- return $this->getEventHandlers($name)->remove($handler)!==false;
- else
- return false;
- }
- public function raiseEvent($name,$event)
- {
- $name=strtolower($name);
- if(isset($this->_e[$name]))
- {
- foreach($this->_e[$name] as $handler)
- {
- if(is_string($handler))
- call_user_func($handler,$event);
- elseif(is_callable($handler,true))
- {
- if(is_array($handler))
- {
- // an array: 0 - object, 1 - method name
- list($object,$method)=$handler;
- if(is_string($object)) // static method call
- call_user_func($handler,$event);
- elseif(method_exists($object,$method))
- $object->$method($event);
- else
- throw new CException(Yii::t('yii','Event "{class}.{event}" is attached with an invalid handler "{handler}".',
- array('{class}'=>get_class($this), '{event}'=>$name, '{handler}'=>$handler[1])));
- }
- else // PHP 5.3: anonymous function
- call_user_func($handler,$event);
- }
- else
- throw new CException(Yii::t('yii','Event "{class}.{event}" is attached with an invalid handler "{handler}".',
- array('{class}'=>get_class($this), '{event}'=>$name, '{handler}'=>gettype($handler))));
- // stop further handling if param.handled is set true
- if(($event instanceof CEvent) && $event->handled)
- return;
- }
- }
- elseif(YII_DEBUG && !$this->hasEvent($name))
- throw new CException(Yii::t('yii','Event "{class}.{event}" is not defined.',
- array('{class}'=>get_class($this), '{event}'=>$name)));
- }
- public function evaluateExpression($_expression_,$_data_=array())
- {
- if(is_string($_expression_))
- {
- extract($_data_);
- return eval('return '.$_expression_.';');
- }
- else
- {
- $_data_[]=$this;
- return call_user_func_array($_expression_, $_data_);
- }
- }
- }
- class CEvent extends CComponent
- {
- public $sender;
- public $handled=false;
- public $params;
- public function __construct($sender=null,$params=null)
- {
- $this->sender=$sender;
- $this->params=$params;
- }
- }
- class CEnumerable
- {
- }
- abstract class CModule extends CComponent
- {
- public $preload=array();
- public $behaviors=array();
- private $_id;
- private $_parentModule;
- private $_basePath;
- private $_modulePath;
- private $_params;
- private $_modules=array();
- private $_moduleConfig=array();
- private $_components=array();
- private $_componentConfig=array();
- public function __construct($id,$parent,$config=null)
- {
- $this->_id=$id;
- $this->_parentModule=$parent;
- // set basePath at early as possible to avoid trouble
- if(is_string($config))
- $config=require($config);
- if(isset($config['basePath']))
- {
- $this->setBasePath($config['basePath']);
- unset($config['basePath']);
- }
- Yii::setPathOfAlias($id,$this->getBasePath());
- $this->preinit();
- $this->configure($config);
- $this->attachBehaviors($this->behaviors);
- $this->preloadComponents();
- $this->init();
- }
- public function __get($name)
- {
- if($this->hasComponent($name))
- return $this->getComponent($name);
- else
- return parent::__get($name);
- }
- public function __isset($name)
- {
- if($this->hasComponent($name))
- return $this->getComponent($name)!==null;
- else
- return parent::__isset($name);
- }
- public function getId()
- {
- return $this->_id;
- }
- public function setId($id)
- {
- $this->_id=$id;
- }
- public function getBasePath()
- {
- if($this->_basePath===null)
- {
- $class=new ReflectionClass(get_class($this));
- $this->_basePath=dirname($class->getFileName());
- }
- return $this->_basePath;
- }
- public function setBasePath($path)
- {
- if(($this->_basePath=realpath($path))===false || !is_dir($this->_basePath))
- throw new CException(Yii::t('yii','Base path "{path}" is not a valid directory.',
- array('{path}'=>$path)));
- }
- public function getParams()
- {
- if($this->_params!==null)
- return $this->_params;
- else
- {
- $this->_params=new CAttributeCollection;
- $this->_params->caseSensitive=true;
- return $this->_params;
- }
- }
- public function setParams($value)
- {
- $params=$this->getParams();
- foreach($value as $k=>$v)
- $params->add($k,$v);
- }
- public function getModulePath()
- {
- if($this->_modulePath!==null)
- return $this->_modulePath;
- else
- return $this->_modulePath=$this->getBasePath().DIRECTORY_SEPARATOR.'modules';
- }
- public function setModulePath($value)
- {
- if(($this->_modulePath=realpath($value))===false || !is_dir($this->_modulePath))
- throw new CException(Yii::t('yii','The module path "{path}" is not a valid directory.',
- array('{path}'=>$value)));
- }
- public function setImport($aliases)
- {
- foreach($aliases as $alias)
- Yii::import($alias);
- }
- public function setAliases($mappings)
- {
- foreach($mappings as $name=>$alias)
- {
- if(($path=Yii::getPathOfAlias($alias))!==false)
- Yii::setPathOfAlias($name,$path);
- else
- Yii::setPathOfAlias($name,$alias);
- }
- }
- public function getParentModule()
- {
- return $this->_parentModule;
- }
- public function getModule($id)
- {
- if(isset($this->_modules[$id]) || array_key_exists($id,$this->_modules))
- return $this->_modules[$id];
- elseif(isset($this->_moduleConfig[$id]))
- {
- $config=$this->_moduleConfig[$id];
- if(!isset($config['enabled']) || $config['enabled'])
- {
- $class=$config['class'];
- unset($config['class'], $config['enabled']);
- if($this===Yii::app())
- $module=Yii::createComponent($class,$id,null,$config);
- else
- $module=Yii::createComponent($class,$this->getId().'/'.$id,$this,$config);
- return $this->_modules[$id]=$module;
- }
- }
- }
- public function hasModule($id)
- {
- return isset($this->_moduleConfig[$id]) || isset($this->_modules[$id]);
- }
- public function getModules()
- {
- return $this->_moduleConfig;
- }
- public function setModules($modules,$merge=true)
- {
- foreach($modules as $id=>$module)
- {
- if(is_int($id))
- {
- $id=$module;
- $module=array();
- }
- if(isset($this->_moduleConfig[$id]) && $merge)
- $this->_moduleConfig[$id]=CMap::mergeArray($this->_moduleConfig[$id],$module);
- else
- {
- if(!isset($module['class']))
- {
- if (Yii::getPathOfAlias($id)===false)
- Yii::setPathOfAlias($id,$this->getModulePath().DIRECTORY_SEPARATOR.$id);
- $module['class']=$id.'.'.ucfirst($id).'Module';
- }
- $this->_moduleConfig[$id]=$module;
- }
- }
- }
- public function hasComponent($id)
- {
- return isset($this->_components[$id]) || isset($this->_componentConfig[$id]);
- }
- public function getComponent($id,$createIfNull=true)
- {
- if(isset($this->_components[$id]))
- return $this->_components[$id];
- elseif(isset($this->_componentConfig[$id]) && $createIfNull)
- {
- $config=$this->_componentConfig[$id];
- if(!isset($config['enabled']) || $config['enabled'])
- {
- unset($config['enabled']);
- $component=Yii::createComponent($config);
- $component->init();
- return $this->_components[$id]=$component;
- }
- }
- }
- public function setComponent($id,$component,$merge=true)
- {
- if($component===null)
- {
- unset($this->_components[$id]);
- return;
- }
- elseif($component instanceof IApplicationComponent)
- {
- $this->_components[$id]=$component;
- if(!$component->getIsInitialized())
- $component->init();
- return;
- }
- elseif(isset($this->_components[$id]))
- {
- if(isset($component['class']) && get_class($this->_components[$id])!==$component['class'])
- {
- unset($this->_components[$id]);
- $this->_componentConfig[$id]=$component; //we should ignore merge here
- return;
- }
- foreach($component as $key=>$value)
- {
- if($key!=='class')
- $this->_components[$id]->$key=$value;
- }
- }
- elseif(isset($this->_componentConfig[$id]['class'],$component['class'])
- && $this->_componentConfig[$id]['class']!==$component['class'])
- {
- $this->_componentConfig[$id]=$component; //we should ignore merge here
- return;
- }
- if(isset($this->_componentConfig[$id]) && $merge)
- $this->_componentConfig[$id]=CMap::mergeArray($this->_componentConfig[$id],$component);
- else
- $this->_componentConfig[$id]=$component;
- }
- public function getComponents($loadedOnly=true)
- {
- if($loadedOnly)
- return $this->_components;
- else
- return array_merge($this->_componentConfig, $this->_components);
- }
- public function setComponents($components,$merge=true)
- {
- foreach($components as $id=>$component)
- $this->setComponent($id,$component,$merge);
- }
- public function configure($config)
- {
- if(is_array($config))
- {
- foreach($config as $key=>$value)
- $this->$key=$value;
- }
- }
- protected function preloadComponents()
- {
- foreach($this->preload as $id)
- $this->getComponent($id);
- }
- protected function preinit()
- {
- }
- protected function init()
- {
- }
- }
- abstract class CApplication extends CModule
- {
- public $name='My Application';
- public $charset='UTF-8';
- public $sourceLanguage='en_us';
- public $localeClass='CLocale';
- private $_id;
- private $_basePath;
- private $_runtimePath;
- private $_extensionPath;
- private $_globalState;
- private $_stateChanged;
- private $_ended=false;
- private $_language;
- private $_homeUrl;
- abstract public function processRequest();
- public function __construct($config=null)
- {
- Yii::setApplication($this);
- // set basePath at early as possible to avoid trouble
- if(is_string($config))
- $config=require($config);
- if(isset($config['basePath']))
- {
- $this->setBasePath($config['basePath']);
- unset($config['basePath']);
- }
- else
- $this->setBasePath('protected');
- Yii::setPathOfAlias('application',$this->getBasePath());
- Yii::setPathOfAlias('webroot',dirname($_SERVER['SCRIPT_FILENAME']));
- if(isset($config['extensionPath']))
- {
- $this->setExtensionPath($config['extensionPath']);
- unset($config['extensionPath']);
- }
- else
- Yii::setPathOfAlias('ext',$this->getBasePath().DIRECTORY_SEPARATOR.'extensions');
- if(isset($config['aliases']))
- {
- $this->setAliases($config['aliases']);
- unset($config['aliases']);
- }
- $this->preinit();
- $this->initSystemHandlers();
- $this->registerCoreComponents();
- $this->configure($config);
- $this->attachBehaviors($this->behaviors);
- $this->preloadComponents();
- $this->init();
- }
- public function run()
- {
- if($this->hasEventHandler('onBeginRequest'))
- $this->onBeginRequest(new CEvent($this));
- register_shutdown_function(array($this,'end'),0,false);
- $this->processRequest();
- if($this->hasEventHandler('onEndRequest'))
- $this->onEndRequest(new CEvent($this));
- }
- public function end($status=0,$exit=true)
- {
- if($this->hasEventHandler('onEndRequest'))
- $this->onEndRequest(new CEvent($this));
- if($exit)
- exit($status);
- }
- public function onBeginRequest($event)
- {
- $this->raiseEvent('onBeginRequest',$event);
- }
- public function onEndRequest($event)
- {
- if(!$this->_ended)
- {
- $this->_ended=true;
- $this->raiseEvent('onEndRequest',$event);
- }
- }
- public function getId()
- {
- if($this->_id!==null)
- return $this->_id;
- else
- return $this->_id=sprintf('%x',crc32($this->getBasePath().$this->name));
- }
- public function setId($id)
- {
- $this->_id=$id;
- }
- public function getBasePath()
- {
- return $this->_basePath;
- }
- public function setBasePath($path)
- {
- if(($this->_basePath=realpath($path))===false || !is_dir($this->_basePath))
- throw new CException(Yii::t('yii','Application base path "{path}" is not a valid directory.',
- array('{path}'=>$path)));
- }
- public function getRuntimePath()
- {
- if($this->_runtimePath!==null)
- return $this->_runtimePath;
- else
- {
- $this->setRuntimePath($this->getBasePath().DIRECTORY_SEPARATOR.'runtime');
- return $this->_runtimePath;
- }
- }
- public function setRuntimePath($path)
- {
- if(($runtimePath=realpath($path))===false || !is_dir($runtimePath) || !is_writable($runtimePath))
- throw new CException(Yii::t('yii','Application runtime path "{path}" is not valid. Please make sure it is a directory writable by the Web server process.',
- array('{path}'=>$path)));
- $this->_runtimePath=$runtimePath;
- }
- public function getExtensionPath()
- {
- return Yii::getPathOfAlias('ext');
- }
- public function setExtensionPath($path)
- {
- if(($extensionPath=realpath($path))===false || !is_dir($extensionPath))
- throw new CException(Yii::t('yii','Extension path "{path}" does not exist.',
- array('{path}'=>$path)));
- Yii::setPathOfAlias('ext',$extensionPath);
- }
- public function getLanguage()
- {
- return $this->_language===null ? $this->sourceLanguage : $this->_language;
- }
- public function setLanguage($language)
- {
- $this->_language=$language;
- }
- public function getTimeZone()
- {
- return date_default_timezone_get();
- }
- public function setTimeZone($value)
- {
- date_default_timezone_set($value);
- }
- public function findLocalizedFile($srcFile,$srcLanguage=null,$language=null)
- {
- if($srcLanguage===null)
- $srcLanguage=$this->sourceLanguage;
- if($language===null)
- $language=$this->getLanguage();
- if($language===$srcLanguage)
- return $srcFile;
- $desiredFile=dirname($srcFile).DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.basename($srcFile);
- return is_file($desiredFile) ? $desiredFile : $srcFile;
- }
- public function getLocale($localeID=null)
- {
- return call_user_func_array(array($this->localeClass, 'getInstance'),array($localeID===null?$this->getLanguage():$localeID));
- }
- public function getLocaleDataPath()
- {
- $vars=get_class_vars($this->localeClass);
- if(empty($vars['dataPath']))
- return Yii::getPathOfAlias('system.i18n.data');
- return $vars['dataPath'];
- }
- public function setLocaleDataPath($value)
- {
- $property=new ReflectionProperty($this->localeClass,'dataPath');
- $property->setValue($value);
- }
- public function getNumberFormatter()
- {
- return $this->getLocale()->getNumberFormatter();
- }
- public function getDateFormatter()
- {
- return $this->getLocale()->getDateFormatter();
- }
- public function getDb()
- {
- return $this->getComponent('db');
- }
- public function getErrorHandler()
- {
- return $this->getComponent('errorHandler');
- }
- public function getSecurityManager()
- {
- return $this->getComponent('securityManager');
- }
- public function getStatePersister()
- {
- return $this->getComponent('statePersister');
- }
- public function getCache()
- {
- return $this->getComponent('cache');
- }
- public function getCoreMessages()
- {
- return $this->getComponent('coreMessages');
- }
- public function getMessages()
- {
- return $this->getComponent('messages');
- }
- public function getRequest()
- {
- return $this->getComponent('request');
- }
- public function getUrlManager()
- {
- return $this->getComponent('urlManager');
- }
- public function getController()
- {
- return null;
- }
- public function createUrl($route,$params=array(),$ampersand='&')
- {
- return $this->getUrlManager()->createUrl($route,$params,$ampersand);
- }
- public function createAbsoluteUrl($route,$params=array(),$schema='',$ampersand='&')
- {
- $url=$this->createUrl($route,$params,$ampersand);
- if(strpos($url,'http')===0)
- return $url;
- else
- return $this->getRequest()->getHostInfo($schema).$url;
- }
- public function getBaseUrl($absolute=false)
- {
- return $this->getRequest()->getBaseUrl($absolute);
- }
- public function getHomeUrl()
- {
- if($this->_homeUrl===null)
- {
- if($this->getUrlManager()->showScriptName)
- return $this->getRequest()->getScriptUrl();
- else
- return $this->getRequest()->getBaseUrl().'/';
- }
- else
- return $this->_homeUrl;
- }
- public function setHomeUrl($value)
- {
- $this->_homeUrl=$value;
- }
- public function getGlobalState($key,$defaultValue=null)
- {
- if($this->_globalState===null)
- $this->loadGlobalState();
- if(isset($this->_globalState[$key]))
- return $this->_globalState[$key];
- else
- return $defaultValue;
- }
- public function setGlobalState($key,$value,$defaultValue=null)
- {
- if($this->_globalState===null)
- $this->loadGlobalState();
- $changed=$this->_stateChanged;
- if($value===$defaultValue)
- {
- if(isset($this->_globalState[$key]))
- {
- unset($this->_globalState[$key]);
- $this->_stateChanged=true;
- }
- }
- elseif(!isset($this->_globalState[$key]) || $this->_globalState[$key]!==$value)
- {
- $this->_globalState[$key]=$value;
- $this->_stateChanged=true;
- }
- if($this->_stateChanged!==$changed)
- $this->attachEventHandler('onEndRequest',array($this,'saveGlobalState'));
- }
- public function clearGlobalState($key)
- {
- $this->setGlobalState($key,true,true);
- }
- public function loadGlobalState()
- {
- $persister=$this->getStatePersister();
- if(($this->_globalState=$persister->load())===null)
- $this->_globalState=array();
- $this->_stateChanged=false;
- $this->detachEventHandler('onEndRequest',array($this,'saveGlobalState'));
- }
- public function saveGlobalState()
- {
- if($this->_stateChanged)
- {
- $this->_stateChanged=false;
- $this->detachEventHandler('onEndRequest',array($this,'saveGlobalState'));
- $this->getStatePersister()->save($this->_globalState);
- }
- }
- public function handleException($exception)
- {
- // disable error capturing to avoid recursive errors
- restore_error_handler();
- restore_exception_handler();
- $category='exception.'.get_class($exception);
- if($exception instanceof CHttpException)
- $category.='.'.$exception->statusCode;
- // php <5.2 doesn't support string conversion auto-magically
- $message=$exception->__toString();
- if(isset($_SERVER['REQUEST_URI']))
- $message.="\nREQUEST_URI=".$_SERVER['REQUEST_URI'];
- if(isset($_SERVER['HTTP_REFERER']))
- $message.="\nHTTP_REFERER=".$_SERVER['HTTP_REFERER'];
- $message.="\n---";
- Yii::log($message,CLogger::LEVEL_ERROR,$category);
- try
- {
- $event=new CExceptionEvent($this,$exception);
- $this->onException($event);
- if(!$event->handled)
- {
- // try an error handler
- if(($handler=$this->getErrorHandler())!==null)
- $handler->handle($event);
- else
- $this->displayException($exception);
- }
- }
- catch(Exception $e)
- {
- $this->displayException($e);
- }
- try
- {
- $this->end(1);
- }
- catch(Exception $e)
- {
- // use the most primitive way to log error
- $msg = get_class($e).': '.$e->getMessage().' ('.$e->getFile().':'.$e->getLine().")\n";
- $msg .= $e->getTraceAsString()."\n";
- $msg .= "Previous exception:\n";
- $msg .= get_class($exception).': '.$exception->getMessage().' ('.$exception->getFile().':'.$exception->getLine().")\n";
- $msg .= $exception->getTraceAsString()."\n";
- $msg .= '$_SERVER='.var_export($_SERVER,true);
- error_log($msg);
- exit(1);
- }
- }
- public function handleError($code,$message,$file,$line)
- {
- if($code & error_reporting())
- {
- // disable error capturing to avoid recursive errors
- restore_error_handler();
- restore_exception_handler();
- $log="$message ($file:$line)\nStack trace:\n";
- $trace=debug_backtrace();
- // skip the first 3 stacks as they do not tell the error position
- if(count($trace)>3)
- $trace=array_slice($trace,3);
- foreach($trace as $i=>$t)
- {
- if(!isset($t['file']))
- $t['file']='unknown';
- if(!isset($t['line']))
- $t['line']=0;
- if(!isset($t['function']))
- $t['function']='unknown';
- $log.="#$i {$t['file']}({$t['line']}): ";
- if(isset($t['object']) && is_object($t['object']))
- $log.=get_class($t['object']).'->';
- $log.="{$t['function']}()\n";
- }
- if(isset($_SERVER['REQUEST_URI']))
- $log.='REQUEST_URI='.$_SERVER['REQUEST_URI'];
- Yii::log($log,CLogger::LEVEL_ERROR,'php');
- try
- {
- Yii::import('CErrorEvent',true);
- $event=new CErrorEvent($this,$code,$message,$file,$line);
- $this->onError($event);
- if(!$event->handled)
- {
- // try an error handler
- if(($handler=$this->getErrorHandler())!==null)
- $handler->handle($event);
- else
- $this->displayError($code,$message,$file,$line);
- }
- }
- catch(Exception $e)
- {
- $this->displayException($e);
- }
- try
- {
- $this->end(1);
- }
- catch(Exception $e)
- {
- // use the most primitive way to log error
- $msg = get_class($e).': '.$e->getMessage().' ('.$e->getFile().':'.$e->getLine().")\n";
- $msg .= $e->getTraceAsString()."\n";
- $msg .= "Previous error:\n";
- $msg .= $log."\n";
- $msg .= '$_SERVER='.var_export($_SERVER,true);
- error_log($msg);
- exit(1);
- }
- }
- }
- public function onException($event)
- {
- $this->raiseEvent('onException',$event);
- }
- public function onError($event)
- {
- $this->raiseEvent('onError',$event);
- }
- public function displayError($code,$message,$file,$line)
- {
- if(YII_DEBUG)
- {
- echo "<h1>PHP Error [$code]</h1>\n";
- echo "<p>$message ($file:$line)</p>\n";
- echo '<pre>';
- $trace=debug_backtrace();
- // skip the first 3 stacks as they do not tell the error position
- if(count($trace)>3)
- $trace=array_slice($trace,3);
- foreach($trace as $i=>$t)
- {
- if(!isset($t['file']))
- $t['file']='unknown';
- if(!isset($t['line']))
- $t['line']=0;
- if(!isset($t['function']))
- $t['function']='unknown';
- echo "#$i {$t['file']}({$t['line']}): ";
- if(isset($t['object']) && is_object($t['object']))
- echo get_class($t['object']).'->';
- echo "{$t['function']}()\n";
- }
- echo '</pre>';
- }
- else
- {
- echo "<h1>PHP Error [$code]</h1>\n";
- echo "<p>$message</p>\n";
- }
- }
- public function displayException($exception)
- {
- if(YII_DEBUG)
- {
- echo '<h1>'.get_class($exception)."</h1>\n";
- echo '<p>'.$exception->getMessage().' ('.$exception->getFile().':'.$exception->getLine().')</p>';
- echo '<pre>'.$exception->getTraceAsString().'</pre>';
- }
- else
- {
- echo '<h1>'.get_class($exception)."</h1>\n";
- echo '<p>'.$exception->getMessage().'</p>';
- }
- }
- protected function initSystemHandlers()
- {
- if(YII_ENABLE_EXCEPTION_HANDLER)
- set_exception_handler(array($this,'handleException'));
- if(YII_ENABLE_ERROR_HANDLER)
- set_error_handler(array($this,'handleError'),error_reporting());
- }
- protected function registerCoreComponents()
- {
- $components=array(
- 'coreMessages'=>array(
- 'class'=>'CPhpMessageSource',
- 'language'=>'en_us',
- 'basePath'=>YII_PATH.DIRECTORY_SEPARATOR.'messages',
- ),
- 'db'=>array(
- 'class'=>'CDbConnection',
- ),
- 'messages'=>array(
- 'class'=>'CPhpMessageSource',
- ),
- 'errorHandler'=>array(
- 'class'=>'CErrorHandler',
- ),
- 'securityManager'=>array(
- 'class'=>'CSecurityManager',
- ),
- 'statePersister'=>array(
- 'class'=>'CStatePersister',
- ),
- 'urlManager'=>array(
- 'class'=>'CUrlManager',
- ),
- 'request'=>array(
- 'class'=>'CHttpRequest',
- ),
- 'format'=>array(
- 'class'=>'CFormatter',
- ),
- );
- $this->setComponents($components);
- }
- }
- class CWebApplication extends CApplication
- {
- public $defaultController='site';
- public $layout='main';
- public $controllerMap=array();
- public $catchAllRequest;
- public $controllerNamespace;
- private $_controllerPath;
- private $_viewPath;
- private $_systemViewPath;
- private $_layoutPath;
- private $_controller;
- private $_theme;
- public function processRequest()
- {
- if(is_array($this->catchAllRequest) && isset($this->catchAllRequest[0]))
- {
- $route=$this->catchAllRequest[0];
- foreach(array_splice($this->catchAllRequest,1) as $name=>$value)
- $_GET[$name]=$value;
- }
- else
- $route=$this->getUrlManager()->parseUrl($this->getRequest());
- $this->runController($route);
- }
- protected function registerCoreComponents()
- {
- parent::registerCoreComponents();
- $components=array(
- 'session'=>array(
- 'class'=>'CHttpSession',
- ),
- 'assetManager'=>array(
- 'class'=>'CAssetManager',
- ),
- 'user'=>array(
- 'class'=>'CWebUser',
- ),
- 'themeManager'=>array(
- 'class'=>'CThemeManager',
- ),
- 'authManager'=>array(
- 'class'=>'CPhpAuthManager',
- ),
- 'clientScript'=>array(
- 'class'=>'CClientScript',
- ),
- 'widgetFactory'=>array(
- 'class'=>'CWidgetFactory',
- ),
- );
- $this->setComponents($components);
- }
- public function getAuthManager()
- {
- return $this->getComponent('authManager');
- }
- public function getAssetManager()
- {
- return $this->getComponent('assetManager');
- }
- public function getSession()
- {
- return $this->getComponent('session');
- }
- public function getUser()
- {
- return $this->getComponent('user');
- }
- public function getViewRenderer()
- {
- return $this->getComponent('viewRenderer');
- }
- public function getClientScript()
- {
- return $this->getComponent('clientScript');
- }
- public function getWidgetFactory()
- {
- return $this->getComponent('widgetFactory');
- }
- public function getThemeManager()
- {
- return $this->getComponent('themeManager');
- }
- public function getTheme()
- {
- if(is_string($this->_theme))
- $this->_theme=$this->getThemeManager()->getTheme($this->_theme);
- return $this->_theme;
- }
- public function setTheme($value)
- {
- $this->_theme=$value;
- }
- public function runController($route)
- {
- if(($ca=$this->createController($route))!==null)
- {
- list($controller,$actionID)=$ca;
- $oldController=$this->_controller;
- $this->_controller=$controller;
- $controller->init();
- $controller->run($actionID);
- $this->_controller=$oldController;
- }
- else
- throw new CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',
- array('{route}'=>$route===''?$this->defaultController:$route)));
- }
- public function createController($route,$owner=null)
- {
- if($owner===null)
- $owner=$this;
- if(($route=trim($route,'/'))==='')
- $route=$owner->defaultController;
- $caseSensitive=$this->getUrlManager()->caseSensitive;
- $route.='/';
- while(($pos=strpos($route,'/'))!==false)
- {
- $id=substr($route,0,$pos);
- if(!preg_match('/^\w+$/',$id))
- return null;
- if(!$caseSensitive)
- $id=strtolower($id);
- $route=(string)substr($route,$pos+1);
- if(!isset($basePath)) // first segment
- {
- if(isset($owner->controllerMap[$id]))
- {
- return array(
- Yii::createComponent($owner->controllerMap[$id],$id,$owner===$this?null:$owner),
- $this->parseActionParams($route),
- );
- }
- if(($module=$owner->getModule($id))!==null)
- return $this->createController($route,$module);
- $basePath=$owner->getControllerPath();
- $controllerID='';
- }
- else
- $controllerID.='/';
- $className=ucfirst($id).'Controller';
- $classFile=$basePath.DIRECTORY_SEPARATOR.$className.'.php';
- if($owner->controllerNamespace!==null)
- $className=$owner->controllerNamespace.'\\'.str_replace('/','\\',$controllerID).$className;
- if(is_file($classFile))
- {
- if(!class_exists($className,false))
- require($classFile);
- if(class_exists($className,false) && is_subclass_of($className,'CController'))
- {
- $id[0]=strtolower($id[0]);
- return array(
- new $className($controllerID.$id,$owner===$this?null:$owner),
- $this->parseActionParams($route),
- );
- }
- return null;
- }
- $controllerID.=$id;
- $basePath.=DIRECTORY_SEPARATOR.$id;
- }
- }
- protected function parseActionParams($pathInfo)
- {
- if(($pos=strpos($pathInfo,'/'))!==false)
- {
- $manager=$this->getUrlManager();
- $manager->parsePathInfo((string)substr($pathInfo,$pos+1));
- $actionID=substr($pathInfo,0,$pos);
- return $manager->caseSensitive ? $actionID : strtolower($actionID);
- }
- else
- return $pathInfo;
- }
- public function getController()
- {
- return $this->_controller;
- }
- public function setController($value)
- {
- $this->_controller=$value;
- }
- public function getControllerPath()
- {
- if($this->_controllerPath!==null)
- return $this->_controllerPath;
- else
- return $this->_controllerPath=$this->getBasePath().DIRECTORY_SEPARATOR.'controllers';
- }
- public function setControllerPath($value)
- {
- if(($this->_controllerPath=realpath($value))===false || !is_dir($this->_controllerPath))
- throw new CException(Yii::t('yii','The controller path "{path}" is not a valid directory.',
- array('{path}'=>$value)));
- }
- public function getViewPath()
- {
- if($this->_viewPath!==null)
- return $this->_viewPath;
- else
- return $this->_viewPath=$this->getBasePath().DIRECTORY_SEPARATOR.'views';
- }
- public function setViewPath($path)
- {
- if(($this->_viewPath=realpath($path))===false || !is_dir($this->_viewPath))
- throw new CException(Yii::t('yii','The view path "{path}" is not a valid directory.',
- array('{path}'=>$path)));
- }
- public function getSystemViewPath()
- {
- if($this->_systemViewPath!==null)
- return $this->_systemViewPath;
- else
- return $this->_systemViewPath=$this->getViewPath().DIRECTORY_SEPARATOR.'system';
- }
- public function setSystemViewPath($path)
- {
- if(($this->_systemViewPath=realpath($path))===false || !is_dir($this->_systemViewPath))
- throw new CException(Yii::t('yii','The system view path "{path}" is not a valid directory.',
- array('{path}'=>$path)));
- }
- public function getLayoutPath()
- {
- if($this->_layoutPath!==null)
- return $this->_layoutPath;
- else
- return $this->_layoutPath=$this->getViewPath().DIRECTORY_SEPARATOR.'layouts';
- }
- public function setLayoutPath($path)
- {
- if(($this->_layoutPath=realpath($path))===false || !is_dir($this->_layoutPath))
- throw new CException(Yii::t('yii','The layout path "{path}" is not a valid directory.',
- array('{path}'=>$path)));
- }
- public function beforeControllerAction($controller,$action)
- {
- return true;
- }
- public function afterControllerAction($controller,$action)
- {
- }
- public function findModule($id)
- {
- if(($controller=$this->getController())!==null && ($module=$controller->getModule())!==null)
- {
- do
- {
- if(($m=$module->getModule($id))!==null)
- return $m;
- } while(($module=$module->getParentModule())!==null);
- }
- if(($m=$this->getModule($id))!==null)
- return $m;
- }
- protected function init()
- {
- parent::init();
- // preload 'request' so that it has chance to respond to onBeginRequest event.
- $this->getRequest();
- }
- }
- class CMap extends CComponent implements IteratorAggregate,ArrayAccess,Countable
- {
- private $_d=array();
- private $_r=false;
- public function __construct($data=null,$readOnly=false)
- {
- if($data!==null)
- $this->copyFrom($data);
- $this->setReadOnly($readOnly);
- }
- public function getReadOnly()
- {
- return $this->_r;
- }
- protected function setReadOnly($value)
- {
- $this->_r=$value;
- }
- public function getIterator()
- {
- return new CMapIterator($this->_d);
- }
- public function count()
- {
- return $this->getCount();
- }
- public function getCount()
- {
- return count($this->_d);
- }
- public function getKeys()
- {
- return array_keys($this->_d);
- }
- public function itemAt($key)
- {
- if(isset($this->_d[$key]))
- return $this->_d[$key];
- else
- return null;
- }
- public function add($key,$value)
- {
- if(!$this->_r)
- {
- if($key===null)
- $this->_d[]=$value;
- else
- $this->_d[$key]=$value;
- }
- else
- throw new CException(Yii::t('yii','The map is read only.'));
- }
- public function remove($key)
- {
- if(!$this->_r)
- {
- if(isset($this->_d[$key]))
- {
- $value=$this->_d[$key];
- unset($this->_d[$key]);
- return $value;
- }
- else
- {
- // it is possible the value is null, which is not detected by isset
- unset($this->_d[$key]);
- return null;
- }
- }
- else
- throw new CException(Yii::t('yii','The map is read only.'));
- }
- public function clear()
- {
- foreach(array_keys($this->_d) as $key)
- $this->remove($key);
- }
- public function contains($key)
- {
- return isset($this->_d[$key]) || array_key_exists($key,$this->_d);
- }
- public function toArray()
- {
- return $this->_d;
- }
- public function copyFrom($data)
- {
- if(is_array($data) || $data instanceof Traversable)
- {
- if($this->getCount()>0)
- $this->clear();
- if($data instanceof CMap)
- $data=$data->_d;
- foreach($data as $key=>$value)
- $this->add($key,$value);
- }
- elseif($data!==null)
- throw new CException(Yii::t('yii','Map data must be an array or an object implementing Traversable.'));
- }
- public function mergeWith($data,$recursive=true)
- {
- if(is_array($data) || $data instanceof Traversable)
- {
- if($data instanceof CMap)
- $data=$data->_d;
- if($recursive)
- {
- if($data instanceof Traversable)
- {
- $d=array();
- foreach($data as $key=>$value)
- $d[$key]=$value;
- $this->_d=self::mergeArray($this->_d,$d);
- }
- else
- $this->_d=self::mergeArray($this->_d,$data);
- }
- else
- {
- foreach($data as $key=>$value)
- $this->add($key,$value);
- }
- }
- elseif($data!==null)
- throw new CException(Yii::t('yii','Map data must be an array or an object implementing Traversable.'));
- }
- public static function mergeArray($a,$b)
- {
- $args=func_get_args();
- $res=array_shift($args);
- while(!empty($args))
- {
- $next=array_shift($args);
- foreach($next as $k => $v)
- {
- if(is_integer($k))
- isset($res[$k]) ? $res[]=$v : $res[$k]=$v;
- elseif(is_array($v) && isset($res[$k]) && is_array($res[$k]))
- $res[$k]=self::mergeArray($res[$k],$v);
- else
- $res[$k]=$v;
- }
- }
- return $res;
- }
- public function offsetExists($offset)
- {
- return $this->contains($offset);
- }
- public function offsetGet($offset)
- {
- return $this->itemAt($offset);
- }
- public function offsetSet($offset,$item)
- {
- $this->add($offset,$item);
- }
- public function offsetUnset($offset)
- {
- $this->remove($offset);
- }
- }
- class CLogger extends CComponent
- {
- const LEVEL_TRACE='trace';
- const LEVEL_WARNING='warning';
- const LEVEL_ERROR='error';
- const LEVEL_INFO='info';
- const LEVEL_PROFILE='profile';
- public $autoFlush=10000;
- public $autoDump=false;
- private $_logs=array();
- private $_logCount=0;
- private $_levels;
- private $_categories;
- private $_except=array();
- private $_timings;
- private $_processing=false;
- public function log($message,$level='info',$category='application')
- {
- $this->_logs[]=array($message,$level,$category,microtime(true));
- $this->_logCount++;
- if($this->autoFlush>0 && $this->_logCount>=$this->autoFlush && !$this->_processing)
- {
- $this->_processing=true;
- $this->flush($this->autoDump);
- $this->_processing=false;
- }
- }
- public function getLogs($levels='',$categories=array(), $except=array())
- {
- $this->_levels=preg_split('/[\s,]+/',strtolower($levels),-1,PREG_SPLIT_NO_EMPTY);
- if (is_string($categories))
- $this->_categories=preg_split('/[\s,]+/',strtolower($categories),-1,PREG_SPLIT_NO_EMPTY);
- else
- $this->_categories=array_filter(array_map('strtolower',$categories));
- if (is_string($except))
- $this->_except=preg_split('/[\s,]+/',strtolower($except),-1,PREG_SPLIT_NO_EMPTY);
- else
- $this->_except=array_filter(array_map('strtolower',$except));
- $ret=$this->_logs;
- if(!empty($levels))
- $ret=array_values(array_filter($ret,array($this,'filterByLevel')));
- if(!empty($this->_categories) || !empty($this->_except))
- $ret=array_values(array_filter($ret,array($this,'filterByCategory')));
- return $ret;
- }
- private function filterByCategory($value)
- {
- return $this->filterAllCategories($value, 2);
- }
- private function filterTimingByCategory($value)
- {
- return $this->filterAllCategories($value, 1);
- }
- private function filterAllCategories($value, $index)
- {
- $cat=strtolower($value[$index]);
- $ret=empty($this->_categories);
- foreach($this->_categories as $category)
- {
- if($cat===$category || (($c=rtrim($category,'.*'))!==$category && strpos($cat,$c)===0))
- $ret=true;
- }
- if($ret)
- {
- foreach($this->_except as $category)
- {
- if($cat===$category || (($c=rtrim($category,'.*'))!==$category && strpos($cat,$c)===0))
- $ret=false;
- }
- }
- return $ret;
- }
- private function filterByLevel($value)
- {
- return in_array(strtolower($value[1]),$this->_levels);
- }
- public function getExecutionTime()
- {
- return microtime(true)-YII_BEGIN_TIME;
- }
- public function getMemoryUsage()
- {
- if(function_exists('memory_get_usage'))
- return memory_get_usage();
- else
- {
- $output=array();
- if(strncmp(PHP_OS,'WIN',3)===0)
- {
- exec('tasklist /FI "PID eq ' . getmypid() . '" /FO LIST',$output);
- return isset($output[5])?preg_replace('/[\D]/','',$output[5])*1024 : 0;
- }
- else
- {
- $pid=getmypid();
- exec("ps -eo%mem,rss,pid | grep $pid", $output);
- $output=explode(" ",$output[0]);
- return isset($output[1]) ? $output[1]*1024 : 0;
- }
- }
- }
- public function getProfilingResults($token=null,$categories=null,$refresh=false)
- {
- if($this->_timings===null || $refresh)
- $this->calculateTimings();
- if($token===null && $categories===null)
- return $this->_timings;
- $timings = $this->_timings;
- if($categories!==null) {
- $this->_categories=preg_split('/[\s,]+/',strtolower($categories),-1,PREG_SPLIT_NO_EMPTY);
- $timings=array_filter($timings,array($this,'filterTimingByCategory'));
- }
- $results=array();
- foreach($timings as $timing)
- {
- if($token===null || $timing[0]===$token)
- $results[]=$timing[2];
- }
- return $results;
- }
- private function calculateTimings()
- {
- $this->_timings=array();
- $stack=array();
- foreach($this->_logs as $log)
- {
- if($log[1]!==CLogger::LEVEL_PROFILE)
- continue;
- list($message,$level,$category,$timestamp)=$log;
- if(!strncasecmp($message,'begin:',6))
- {
- $log[0]=substr($message,6);
- $stack[]=$log;
- }
- elseif(!strncasecmp($message,'end:',4))
- {
- $token=substr($message,4);
- if(($last=array_pop($stack))!==null && $last[0]===$token)
- {
- $delta=$log[3]-$last[3];
- $this->_timings[]=array($message,$category,$delta);
- }
- else
- throw new CException(Yii::t('yii','CProfileLogRoute found a mismatching code block "{token}". Make sure the calls to Yii::beginProfile() and Yii::endProfile() be properly nested.',
- array('{token}'=>$token)));
- }
- }
- $now=microtime(true);
- while(($last=array_pop($stack))!==null)
- {
- $delta=$now-$last[3];
- $this->_timings[]=array($last[0],$last[2],$delta);
- }
- }
- public function flush($dumpLogs=false)
- {
- $this->onFlush(new CEvent($this, array('dumpLogs'=>$dumpLogs)));
- $this->_logs=array();
- $this->_logCount=0;
- }
- public function onFlush($event)
- {
- $this->raiseEvent('onFlush', $event);
- }
- }
- abstract class CApplicationComponent extends CComponent implements IApplicationComponent
- {
- public $behaviors=array();
- private $_initialized=false;
- public function init()
- {
- $this->attachBehaviors($this->behaviors);
- $this->_initialized=true;
- }
- public function getIsInitialized()
- {
- return $this->_initialized;
- }
- }
- class CHttpRequest extends CApplicationComponent
- {
- public $enableCookieValidation=false;
- public $enableCsrfValidation=false;
- public $csrfTokenName='YII_CSRF_TOKEN';
- public $csrfCookie;
- private $_requestUri;
- private $_pathInfo;
- private $_scriptFile;
- private $_scriptUrl;
- private $_hostInfo;
- private $_baseUrl;
- private $_cookies;
- private $_preferredAcceptTypes;
- private $_preferredLanguages;
- private $_csrfToken;
- private $_restParams;
- private $_httpVersion;
- public function init()
- {
- parent::init();
- $this->normalizeRequest();
- }
- protected function normalizeRequest()
- {
- // normalize request
- if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc())
- {
- if(isset($_GET))
- $_GET=$this->stripSlashes($_GET);
- if(isset($_POST))
- $_POST=$this->stripSlashes($_POST);
- if(isset($_REQUEST))
- $_REQUEST=$this->stripSlashes($_REQUEST);
- if(isset($_COOKIE))
- $_COOKIE=$this->stripSlashes($_COOKIE);
- }
- if($this->enableCsrfValidation)
- Yii::app()->attachEventHandler('onBeginRequest',array($this,'validateCsrfToken'));
- }
- public function stripSlashes(&$data)
- {
- if(is_array($data))
- {
- if(count($data) == 0)
- return $data;
- $keys=array_map('stripslashes',array_keys($data));
- $data=array_combine($keys,array_values($data));
- return array_map(array($this,'stripSlashes'),$data);
- }
- else
- return stripslashes($data);
- }
- public function getParam($name,$defaultValue=null)
- {
- return isset($_GET[$name]) ? $_GET[$name] : (isset($_POST[$name]) ? $_POST[$name] : $defaultValue);
- }
- public function getQuery($name,$defaultValue=null)
- {
- return isset($_GET[$name]) ? $_GET[$name] : $defaultValue;
- }
- public function getPost($name,$defaultValue=null)
- {
- return isset($_POST[$name]) ? $_POST[$name] : $defaultValue;
- }
- public function getDelete($name,$defaultValue=null)
- {
- if($this->getIsDeleteViaPostRequest())
- return $this->getPost($name, $defaultValue);
- if($this->getIsDeleteRequest())
- {
- $restParams=$this->getRestParams();
- return isset($restParams[$name]) ? $restParams[$name] : $defaultValue;
- }
- else
- return $defaultValue;
- }
- public function getPut($name,$defaultValue=null)
- {
- if($this->getIsPutViaPostRequest())
- return $this->getPost($name, $defaultValue);
- if($this->getIsPutRequest())
- {
- $restParams=$this->getRestParams();
- return isset($restParams[$name]) ? $restParams[$name] : $defaultValue;
- }
- else
- return $defaultValue;
- }
- public function getPatch($name,$defaultValue=null)
- {
- if($this->getIsPatchViaPostRequest())
- return $this->getPost($name, $defaultValue);
- if($this->getIsPatchRequest())
- {
- $restParams=$this->getRestParams();
- return isset($restParams[$name]) ? $restParams[$name] : $defaultValue;
- }
- else
- return $defaultValue;
- }
- public function getRestParams()
- {
- if($this->_restParams===null)
- {
- $result=array();
- if(function_exists('mb_parse_str'))
- mb_parse_str($this->getRawBody(), $result);
- else
- parse_str($this->getRawBody(), $result);
- $this->_restParams=$result;
- }
- return $this->_restParams;
- }
- public function getRawBody()
- {
- static $rawBody;
- if($rawBody===null)
- $rawBody=file_get_contents('php://input');
- return $rawBody;
- }
- public function getUrl()
- {
- return $this->getRequestUri();
- }
- public function getHostInfo($schema='')
- {
- if($this->_hostInfo===null)
- {
- if($secure=$this->getIsSecureConnection())
- $http='https';
- else
- $http='http';
- if(isset($_SERVER['HTTP_HOST']))
- $this->_hostInfo=$http.'://'.$_SERVER['HTTP_HOST'];
- else
- {
- $this->_hostInfo=$http.'://'.$_SERVER['SERVER_NAME'];
- $port=$secure ? $this->getSecurePort() : $this->getPort();
- if(($port!==80 && !$secure) || ($port!==443 && $secure))
- $this->_hostInfo.=':'.$port;
- }
- }
- if($schema!=='')
- {
- $secure=$this->getIsSecureConnection();
- if($secure && $schema==='https' || !$secure && $schema==='http')
- return $this->_hostInfo;
- $port=$schema==='https' ? $this->getSecurePort() : $this->getPort();
- if($port!==80 && $schema==='http' || $port!==443 && $schema==='https')
- $port=':'.$port;
- else
- $port='';
- $pos=strpos($this->_hostInfo,':');
- return $schema.substr($this->_hostInfo,$pos,strcspn($this->_hostInfo,':',$pos+1)+1).$port;
- }
- else
- return $this->_hostInfo;
- }
- public function setHostInfo($value)
- {
- $this->_hostInfo=rtrim($value,'/');
- }
- public function getBaseUrl($absolute=false)
- {
- if($this->_baseUrl===null)
- $this->_baseUrl=rtrim(dirname($this->getScriptUrl()),'\\/');
- return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl;
- }
- public function setBaseUrl($value)
- {
- $this->_baseUrl=$value;
- }
- public function getScriptUrl()
- {
- if($this->_scriptUrl===null)
- {
- $scriptName=basename($_SERVER['SCRIPT_FILENAME']);
- if(basename($_SERVER['SCRIPT_NAME'])===$scriptName)
- $this->_scriptUrl=$_SERVER['SCRIPT_NAME'];
- elseif(basename($_SERVER['PHP_SELF'])===$scriptName)
- $this->_scriptUrl=$_SERVER['PHP_SELF'];
- elseif(isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME'])===$scriptName)
- $this->_scriptUrl=$_SERVER['ORIG_SCRIPT_NAME'];
- elseif(($pos=strpos($_SERVER['PHP_SELF'],'/'.$scriptName))!==false)
- $this->_scriptUrl=substr($_SERVER['SCRIPT_NAME'],0,$pos).'/'.$scriptName;
- elseif(isset($_SERVER['DOCUMENT_ROOT']) && strpos($_SERVER['SCRIPT_FILENAME'],$_SERVER['DOCUMENT_ROOT'])===0)
- $this->_scriptUrl=str_replace('\\','/',str_replace($_SERVER['DOCUMENT_ROOT'],'',$_SERVER['SCRIPT_FILENAME']));
- else
- throw new CException(Yii::t('yii','CHttpRequest is unable to determine the entry script URL.'));
- }
- return $this->_scriptUrl;
- }
- public function setScriptUrl($value)
- {
- $this->_scriptUrl='/'.trim($value,'/');
- }
- public function getPathInfo()
- {
- if($this->_pathInfo===null)
- {
- $pathInfo=$this->getRequestUri();
- if(($pos=strpos($pathInfo,'?'))!==false)
- $pathInfo=substr($pathInfo,0,$pos);
- $pathInfo=$this->decodePathInfo($pathInfo);
- $scriptUrl=$this->getScriptUrl();
- $baseUrl=$this->getBaseUrl();
- if(strpos($pathInfo,$scriptUrl)===0)
- $pathInfo=substr($pathInfo,strlen($scriptUrl));
- elseif($baseUrl==='' || strpos($pathInfo,$baseUrl)===0)
- $pathInfo=substr($pathInfo,strlen($baseUrl));
- elseif(strpos($_SERVER['PHP_SELF'],$scriptUrl)===0)
- $pathInfo=substr($_SERVER['PHP_SELF'],strlen($scriptUrl));
- else
- throw new CException(Yii::t('yii','CHttpRequest is unable to determine the path info of the request.'));
- if($pathInfo==='/')
- $pathInfo='';
- elseif($pathInfo[0]==='/')
- $pathInfo=substr($pathInfo,1);
- if(($posEnd=strlen($pathInfo)-1)>0 && $pathInfo[$posEnd]==='/')
- $pathInfo=substr($pathInfo,0,$posEnd);
- $this->_pathInfo=$pathInfo;
- }
- return $this->_pathInfo;
- }
- protected function decodePathInfo($pathInfo)
- {
- $pathInfo = urldecode($pathInfo);
- // is it UTF-8?
- // http://w3.org/International/questions/qa-forms-utf-8.html
- if(preg_match('%^(?:
- [\x09\x0A\x0D\x20-\x7E] # ASCII
- | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
- | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
- | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
- | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
- | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
- | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
- | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
- )*$%xs', $pathInfo))
- {
- return $pathInfo;
- }
- else
- {
- return utf8_encode($pathInfo);
- }
- }
- public function getRequestUri()
- {
- if($this->_requestUri===null)
- {
- if(isset($_SERVER['HTTP_X_REWRITE_URL'])) // IIS
- $this->_requestUri=$_SERVER['HTTP_X_REWRITE_URL'];
- elseif(isset($_SERVER['REQUEST_URI']))
- {
- $this->_requestUri=$_SERVER['REQUEST_URI'];
- if(!empty($_SERVER['HTTP_HOST']))
- {
- if(strpos($this->_requestUri,$_SERVER['HTTP_HOST'])!==false)
- $this->_requestUri=preg_replace('/^\w+:\/\/[^\/]+/','',$this->_requestUri);
- }
- else
- $this->_requestUri=preg_replace('/^(http|https):\/\/[^\/]+/i','',$this->_requestUri);
- }
- elseif(isset($_SERVER['ORIG_PATH_INFO'])) // IIS 5.0 CGI
- {
- $this->_requestUri=$_SERVER['ORIG_PATH_INFO'];
- if(!empty($_SERVER['QUERY_STRING']))
- $this->_requestUri.='?'.$_SERVER['QUERY_STRING'];
- }
- else
- throw new CException(Yii::t('yii','CHttpRequest is unable to determine the request URI.'));
- }
- return $this->_requestUri;
- }
- public function getQueryString()
- {
- return isset($_SERVER['QUERY_STRING'])?$_SERVER['QUERY_STRING']:'';
- }
- public function getIsSecureConnection()
- {
- return isset($_SERVER['HTTPS']) && (strcasecmp($_SERVER['HTTPS'],'on')===0 || $_SERVER['HTTPS']==1)
- || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'],'https')===0;
- }
- public function getRequestType()
- {
- if(isset($_POST['_method']))
- return strtoupper($_POST['_method']);
- elseif(isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']))
- return strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
- return strtoupper(isset($_SERVER['REQUEST_METHOD'])?$_SERVER['REQUEST_METHOD']:'GET');
- }
- public function getIsPostRequest()
- {
- return isset($_SERVER['REQUEST_METHOD']) && !strcasecmp($_SERVER['REQUEST_METHOD'],'POST');
- }
- public function getIsDeleteRequest()
- {
- return (isset($_SERVER['REQUEST_METHOD']) && !strcasecmp($_SERVER['REQUEST_METHOD'],'DELETE')) || $this->getIsDeleteViaPostRequest();
- }
- protected function getIsDeleteViaPostRequest()
- {
- return isset($_POST['_method']) && !strcasecmp($_POST['_method'],'DELETE');
- }
- public function getIsPutRequest()
- {
- return (isset($_SERVER['REQUEST_METHOD']) && !strcasecmp($_SERVER['REQUEST_METHOD'],'PUT')) || $this->getIsPutViaPostRequest();
- }
- protected function getIsPutViaPostRequest()
- {
- return isset($_POST['_method']) && !strcasecmp($_POST['_method'],'PUT');
- }
- public function getIsPatchRequest()
- {
- return (isset($_SERVER['REQUEST_METHOD']) && !strcasecmp($_SERVER['REQUEST_METHOD'],'PATCH')) || $this->getIsPatchViaPostRequest();
- }
- protected function getIsPatchViaPostRequest()
- {
- return isset($_POST['_method']) && !strcasecmp($_POST['_method'],'PATCH');
- }
- public function getIsAjaxRequest()
- {
- return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH']==='XMLHttpRequest';
- }
- public function getIsFlashRequest()
- {
- return isset($_SERVER['HTTP_USER_AGENT']) && (stripos($_SERVER['HTTP_USER_AGENT'],'Shockwave')!==false || stripos($_SERVER['HTTP_USER_AGENT'],'Flash')!==false);
- }
- public function getServerName()
- {
- return $_SERVER['SERVER_NAME'];
- }
- public function getServerPort()
- {
- return $_SERVER['SERVER_PORT'];
- }
- public function getUrlReferrer()
- {
- return isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:null;
- }
- public function getUserAgent()
- {
- return isset($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:null;
- }
- public function getUserHostAddress()
- {
- return isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:'127.0.0.1';
- }
- public function getUserHost()
- {
- return isset($_SERVER['REMOTE_HOST'])?$_SERVER['REMOTE_HOST']:null;
- }
- public function getScriptFile()
- {
- if($this->_scriptFile!==null)
- return $this->_scriptFile;
- else
- return $this->_scriptFile=realpath($_SERVER['SCRIPT_FILENAME']);
- }
- public function getBrowser($userAgent=null)
- {
- return get_browser($userAgent,true);
- }
- public function getAcceptTypes()
- {
- return isset($_SERVER['HTTP_ACCEPT'])?$_SERVER['HTTP_ACCEPT']:null;
- }
- private $_port;
- public function getPort()
- {
- if($this->_port===null)
- $this->_port=!$this->getIsSecureConnection() && isset($_SERVER['SERVER_PORT']) ? (int)$_SERVER['SERVER_PORT'] : 80;
- return $this->_port;
- }
- public function setPort($value)
- {
- $this->_port=(int)$value;
- $this->_hostInfo=null;
- }
- private $_securePort;
- public function getSecurePort()
- {
- if($this->_securePort===null)
- $this->_securePort=$this->getIsSecureConnection() && isset($_SERVER['SERVER_PORT']) ? (int)$_SERVER['SERVER_PORT'] : 443;
- return $this->_securePort;
- }
- public function setSecurePort($value)
- {
- $this->_securePort=(int)$value;
- $this->_hostInfo=null;
- }
- public function getCookies()
- {
- if($this->_cookies!==null)
- return $this->_cookies;
- else
- return $this->_cookies=new CCookieCollection($this);
- }
- public function redirect($url,$terminate=true,$statusCode=302)
- {
- if(strpos($url,'/')===0 && strpos($url,'//')!==0)
- $url=$this->getHostInfo().$url;
- header('Location: '.$url, true, $statusCode);
- if($terminate)
- Yii::app()->end();
- }
- public static function parseAcceptHeader($header)
- {
- $matches=array();
- $accepts=array();
- // get individual entries with their type, subtype, basetype and params
- preg_match_all('/(?:\G\s?,\s?|^)(\w+|\*)\/(\w+|\*)(?:\+(\w+))?|(?<!^)\G(?:\s?;\s?(\w+)=([\w\.]+))/',$header,$matches);
- // the regexp should (in theory) always return an array of 6 arrays
- if(count($matches)===6)
- {
- $i=0;
- $itemLen=count($matches[1]);
- while($i<$itemLen)
- {
- // fill out a content type
- $accept=array(
- 'type'=>$matches[1][$i],
- 'subType'=>$matches[2][$i],
- 'baseType'=>null,
- 'params'=>array(),
- );
- // fill in the base type if it exists
- if($matches[3][$i]!==null && $matches[3][$i]!=='')
- $accept['baseType']=$matches[3][$i];
- // continue looping while there is no new content type, to fill in all accompanying params
- for($i++;$i<$itemLen;$i++)
- {
- // if the next content type is null, then the item is a param for the current content type
- if($matches[1][$i]===null || $matches[1][$i]==='')
- {
- // if this is the quality param, convert it to a double
- if($matches[4][$i]==='q')
- {
- // sanity check on q value
- $q=(double)$matches[5][$i];
- if($q>1)
- $q=(double)1;
- elseif($q<0)
- $q=(double)0;
- $accept['params'][$matches[4][$i]]=$q;
- }
- else
- $accept['params'][$matches[4][$i]]=$matches[5][$i];
- }
- else
- break;
- }
- // q defaults to 1 if not explicitly given
- if(!isset($accept['params']['q']))
- $accept['params']['q']=(double)1;
- $accepts[] = $accept;
- }
- }
- return $accepts;
- }
- public static function compareAcceptTypes($a,$b)
- {
- // check for equal quality first
- if($a['params']['q']===$b['params']['q'])
- if(!($a['type']==='*' xor $b['type']==='*'))
- if (!($a['subType']==='*' xor $b['subType']==='*'))
- // finally, higher number of parameters counts as greater precedence
- if(count($a['params'])===count($b['params']))
- return 0;
- else
- return count($a['params'])<count($b['params']) ? 1 : -1;
- // more specific takes precedence - whichever one doesn't have a * subType
- else
- return $a['subType']==='*' ? 1 : -1;
- // more specific takes precedence - whichever one doesn't have a * type
- else
- return $a['type']==='*' ? 1 : -1;
- else
- return ($a['params']['q']<$b['params']['q']) ? 1 : -1;
- }
- public function getPreferredAcceptTypes()
- {
- if($this->_preferredAcceptTypes===null)
- {
- $accepts=self::parseAcceptHeader($this->getAcceptTypes());
- usort($accepts,array(get_class($this),'compareAcceptTypes'));
- $this->_preferredAcceptTypes=$accepts;
- }
- return $this->_preferredAcceptTypes;
- }
- public function getPreferredAcceptType()
- {
- $preferredAcceptTypes=$this->getPreferredAcceptTypes();
- return empty($preferredAcceptTypes) ? false : $preferredAcceptTypes[0];
- }
- public function getPreferredLanguages()
- {
- if($this->_preferredLanguages===null)
- {
- $sortedLanguages=array();
- if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) && $n=preg_match_all('/([\w\-_]+)(?:\s*;\s*q\s*=\s*(\d*\.?\d*))?/',$_SERVER['HTTP_ACCEPT_LANGUAGE'],$matches))
- {
- $languages=array();
- for($i=0;$i<$n;++$i)
- {
- $q=$matches[2][$i];
- if($q==='')
- $q=1;
- if($q)
- $languages[]=array((float)$q,$matches[1][$i]);
- }
- usort($languages,create_function('$a,$b','if($a[0]==$b[0]) {return 0;} return ($a[0]<$b[0]) ? 1 : -1;'));
- foreach($languages as $language)
- $sortedLanguages[]=$language[1];
- }
- $this->_preferredLanguages=$sortedLanguages;
- }
- return $this->_preferredLanguages;
- }
- public function getPreferredLanguage($languages=array())
- {
- $preferredLanguages=$this->getPreferredLanguages();
- if(empty($languages)) {
- return !empty($preferredLanguages) ? CLocale::getCanonicalID($preferredLanguages[0]) : false;
- }
- foreach ($preferredLanguages as $preferredLanguage) {
- $preferredLanguage=CLocale::getCanonicalID($preferredLanguage);
- foreach ($languages as $language) {
- $language=CLocale::getCanonicalID($language);
- // en_us==en_us, en==en_us, en_us==en
- if($language===$acceptedLanguage || strpos($acceptedLanguage,$language.'_')===0 || strpos($language,$acceptedLanguage.'_')===0) {
- return $language;
- }
- }
- }
- return reset($languages);
- }
- public function sendFile($fileName,$content,$mimeType=null,$terminate=true)
- {
- if($mimeType===null)
- {
- if(($mimeType=CFileHelper::getMimeTypeByExtension($fileName))===null)
- $mimeType='text/plain';
- }
- $fileSize=(function_exists('mb_strlen') ? mb_strlen($content,'8bit') : strlen($content));
- $contentStart=0;
- $contentEnd=$fileSize-1;
- $httpVersion=$this->getHttpVersion();
- if(isset($_SERVER['HTTP_RANGE']))
- {
- header('Accept-Ranges: bytes');
- //client sent us a multibyte range, can not hold this one for now
- if(strpos($_SERVER['HTTP_RANGE'],',')!==false)
- {
- header("Content-Range: bytes $contentStart-$contentEnd/$fileSize");
- throw new CHttpException(416,'Requested Range Not Satisfiable');
- }
- $range=str_replace('bytes=','',$_SERVER['HTTP_RANGE']);
- //range requests starts from "-", so it means that data must be dumped the end point.
- if($range[0]==='-')
- $contentStart=$fileSize-substr($range,1);
- else
- {
- $range=explode('-',$range);
- $contentStart=$range[0];
- // check if the last-byte-pos presents in header
- if((isset($range[1]) && is_numeric($range[1])))
- $contentEnd=$range[1];
- }
- /* Check the range and make sure it's treated according to the specs.
- * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
- */
- // End bytes can not be larger than $end.
- $contentEnd=($contentEnd > $fileSize) ? $fileSize-1 : $contentEnd;
- // Validate the requested range and return an error if it's not correct.
- $wrongContentStart=($contentStart>$contentEnd || $contentStart>$fileSize-1 || $contentStart<0);
- if($wrongContentStart)
- {
- header("Content-Range: bytes $contentStart-$contentEnd/$fileSize");
- throw new CHttpException(416,'Requested Range Not Satisfiable');
- }
- header("HTTP/$httpVersion 206 Partial Content");
- header("Content-Range: bytes $contentStart-$contentEnd/$fileSize");
- }
- else
- header("HTTP/$httpVersion 200 OK");
- $length=$contentEnd-$contentStart+1; // Calculate new content length
- header('Pragma: public');
- header('Expires: 0');
- header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
- header("Content-Type: $mimeType");
- header('Content-Length: '.$length);
- header("Content-Disposition: attachment; filename=\"$fileName\"");
- header('Content-Transfer-Encoding: binary');
- $content=function_exists('mb_substr') ? mb_substr($content,$contentStart,$length) : substr($content,$contentStart,$length);
- if($terminate)
- {
- // clean up the application first because the file downloading could take long time
- // which may cause timeout of some resources (such as DB connection)
- ob_start();
- Yii::app()->end(0,false);
- ob_end_clean();
- echo $content;
- exit(0);
- }
- else
- echo $content;
- }
- public function xSendFile($filePath, $options=array())
- {
- if(!isset($options['forceDownload']) || $options['forceDownload'])
- $disposition='attachment';
- else
- $disposition='inline';
- if(!isset($options['saveName']))
- $options['saveName']=basename($filePath);
- if(!isset($options['mimeType']))
- {
- if(($options['mimeType']=CFileHelper::getMimeTypeByExtension($filePath))===null)
- $options['mimeType']='text/plain';
- }
- if(!isset($options['xHeader']))
- $options['xHeader']='X-Sendfile';
- if($options['mimeType']!==null)
- header('Content-Type: '.$options['mimeType']);
- header('Content-Disposition: '.$disposition.'; filename="'.$options['saveName'].'"');
- if(isset($options['addHeaders']))
- {
- foreach($options['addHeaders'] as $header=>$value)
- header($header.': '.$value);
- }
- header(trim($options['xHeader']).': '.$filePath);
- if(!isset($options['terminate']) || $options['terminate'])
- Yii::app()->end();
- }
- public function getCsrfToken()
- {
- if($this->_csrfToken===null)
- {
- $cookie=$this->getCookies()->itemAt($this->csrfTokenName);
- if(!$cookie || ($this->_csrfToken=$cookie->value)==null)
- {
- $cookie=$this->createCsrfCookie();
- $this->_csrfToken=$cookie->value;
- $this->getCookies()->add($cookie->name,$cookie);
- }
- }
- return $this->_csrfToken;
- }
- protected function createCsrfCookie()
- {
- $cookie=new CHttpCookie($this->csrfTokenName,sha1(uniqid(mt_rand(),true)));
- if(is_array($this->csrfCookie))
- {
- foreach($this->csrfCookie as $name=>$value)
- $cookie->$name=$value;
- }
- return $cookie;
- }
- public function validateCsrfToken($event)
- {
- if ($this->getIsPostRequest() ||
- $this->getIsPutRequest() ||
- $this->getIsPatchRequest() ||
- $this->getIsDeleteRequest())
- {
- $cookies=$this->getCookies();
- $method=$this->getRequestType();
- switch($method)
- {
- case 'POST':
- $userToken=$this->getPost($this->csrfTokenName);
- break;
- case 'PUT':
- $userToken=$this->getPut($this->csrfTokenName);
- break;
- case 'PATCH':
- $userToken=$this->getPatch($this->csrfTokenName);
- break;
- case 'DELETE':
- $userToken=$this->getDelete($this->csrfTokenName);
- }
- if (!empty($userToken) && $cookies->contains($this->csrfTokenName))
- {
- $cookieToken=$cookies->itemAt($this->csrfTokenName)->value;
- $valid=$cookieToken===$userToken;
- }
- else
- $valid = false;
- if (!$valid)
- throw new CHttpException(400,Yii::t('yii','The CSRF token could not be verified.'));
- }
- }
- public function getHttpVersion()
- {
- if($this->_httpVersion===null)
- {
- if(isset($_SERVER['SERVER_PROTOCOL']) && $_SERVER['SERVER_PROTOCOL']==='HTTP/1.0')
- $this->_httpVersion='1.0';
- else
- $this->_httpVersion='1.1';
- }
- return $this->_httpVersion;
- }
- }
- class CCookieCollection extends CMap
- {
- private $_request;
- private $_initialized=false;
- public function __construct(CHttpRequest $request)
- {
- $this->_request=$request;
- $this->copyfrom($this->getCookies());
- $this->_initialized=true;
- }
- public function getRequest()
- {
- return $this->_request;
- }
- protected function getCookies()
- {
- $cookies=array();
- if($this->_request->enableCookieValidation)
- {
- $sm=Yii::app()->getSecurityManager();
- foreach($_COOKIE as $name=>$value)
- {
- if(is_string($value) && ($value=$sm->validateData($value))!==false)
- $cookies[$name]=new CHttpCookie($name,@unserialize($value));
- }
- }
- else
- {
- foreach($_COOKIE as $name=>$value)
- $cookies[$name]=new CHttpCookie($name,$value);
- }
- return $cookies;
- }
- public function add($name,$cookie)
- {
- if($cookie instanceof CHttpCookie)
- {
- $this->remove($name);
- parent::add($name,$cookie);
- if($this->_initialized)
- $this->addCookie($cookie);
- }
- else
- throw new CException(Yii::t('yii','CHttpCookieCollection can only hold CHttpCookie objects.'));
- }
- public function remove($name,$options=array())
- {
- if(($cookie=parent::remove($name))!==null)
- {
- if($this->_initialized)
- {
- $cookie->configure($options);
- $this->removeCookie($cookie);
- }
- }
- return $cookie;
- }
- protected function addCookie($cookie)
- {
- $value=$cookie->value;
- if($this->_request->enableCookieValidation)
- $value=Yii::app()->getSecurityManager()->hashData(serialize($value));
- if(version_compare(PHP_VERSION,'5.2.0','>='))
- setcookie($cookie->name,$value,$cookie->expire,$cookie->path,$cookie->domain,$cookie->secure,$cookie->httpOnly);
- else
- setcookie($cookie->name,$value,$cookie->expire,$cookie->path,$cookie->domain,$cookie->secure);
- }
- protected function removeCookie($cookie)
- {
- if(version_compare(PHP_VERSION,'5.2.0','>='))
- setcookie($cookie->name,'',0,$cookie->path,$cookie->domain,$cookie->secure,$cookie->httpOnly);
- else
- setcookie($cookie->name,'',0,$cookie->path,$cookie->domain,$cookie->secure);
- }
- }
- class CUrlManager extends CApplicationComponent
- {
- const CACHE_KEY='Yii.CUrlManager.rules';
- const GET_FORMAT='get';
- const PATH_FORMAT='path';
- public $rules=array();
- public $urlSuffix='';
- public $showScriptName=true;
- public $appendParams=true;
- public $routeVar='r';
- public $caseSensitive=true;
- public $matchValue=false;
- public $cacheID='cache';
- public $useStrictParsing=false;
- public $urlRuleClass='CUrlRule';
- private $_urlFormat=self::GET_FORMAT;
- private $_rules=array();
- private $_baseUrl;
- public function init()
- {
- parent::init();
- $this->processRules();
- }
- protected function processRules()
- {
- if(empty($this->rules) || $this->getUrlFormat()===self::GET_FORMAT)
- return;
- if($this->cacheID!==false && ($cache=Yii::app()->getComponent($this->cacheID))!==null)
- {
- $hash=md5(serialize($this->rules));
- if(($data=$cache->get(self::CACHE_KEY))!==false && isset($data[1]) && $data[1]===$hash)
- {
- $this->_rules=$data[0];
- return;
- }
- }
- foreach($this->rules as $pattern=>$route)
- $this->_rules[]=$this->createUrlRule($route,$pattern);
- if(isset($cache))
- $cache->set(self::CACHE_KEY,array($this->_rules,$hash));
- }
- public function addRules($rules,$append=true)
- {
- if ($append)
- {
- foreach($rules as $pattern=>$route)
- $this->_rules[]=$this->createUrlRule($route,$pattern);
- }
- else
- {
- $rules=array_reverse($rules);
- foreach($rules as $pattern=>$route)
- array_unshift($this->_rules, $this->createUrlRule($route,$pattern));
- }
- }
- protected function createUrlRule($route,$pattern)
- {
- if(is_array($route) && isset($route['class']))
- return $route;
- else
- {
- $urlRuleClass=Yii::import($this->urlRuleClass,true);
- return new $urlRuleClass($route,$pattern);
- }
- }
- public function createUrl($route,$params=array(),$ampersand='&')
- {
- unset($params[$this->routeVar]);
- foreach($params as $i=>$param)
- if($param===null)
- $params[$i]='';
- if(isset($params['#']))
- {
- $anchor='#'.$params['#'];
- unset($params['#']);
- }
- else
- $anchor='';
- $route=trim($route,'/');
- foreach($this->_rules as $i=>$rule)
- {
- if(is_array($rule))
- $this->_rules[$i]=$rule=Yii::createComponent($rule);
- if(($url=$rule->createUrl($this,$route,$params,$ampersand))!==false)
- {
- if($rule->hasHostInfo)
- return $url==='' ? '/'.$anchor : $url.$anchor;
- else
- return $this->getBaseUrl().'/'.$url.$anchor;
- }
- }
- return $this->createUrlDefault($route,$params,$ampersand).$anchor;
- }
- protected function createUrlDefault($route,$params,$ampersand)
- {
- if($this->getUrlFormat()===self::PATH_FORMAT)
- {
- $url=rtrim($this->getBaseUrl().'/'.$route,'/');
- if($this->appendParams)
- {
- $url=rtrim($url.'/'.$this->createPathInfo($params,'/','/'),'/');
- return $route==='' ? $url : $url.$this->urlSuffix;
- }
- else
- {
- if($route!=='')
- $url.=$this->urlSuffix;
- $query=$this->createPathInfo($params,'=',$ampersand);
- return $query==='' ? $url : $url.'?'.$query;
- }
- }
- else
- {
- $url=$this->getBaseUrl();
- if(!$this->showScriptName)
- $url.='/';
- if($route!=='')
- {
- $url.='?'.$this->routeVar.'='.$route;
- if(($query=$this->createPathInfo($params,'=',$ampersand))!=='')
- $url.=$ampersand.$query;
- }
- elseif(($query=$this->createPathInfo($params,'=',$ampersand))!=='')
- $url.='?'.$query;
- return $url;
- }
- }
- public function parseUrl($request)
- {
- if($this->getUrlFormat()===self::PATH_FORMAT)
- {
- $rawPathInfo=$request->getPathInfo();
- $pathInfo=$this->removeUrlSuffix($rawPathInfo,$this->urlSuffix);
- foreach($this->_rules as $i=>$rule)
- {
- if(is_array($rule))
- $this->_rules[$i]=$rule=Yii::createComponent($rule);
- if(($r=$rule->parseUrl($this,$request,$pathInfo,$rawPathInfo))!==false)
- return isset($_GET[$this->routeVar]) ? $_GET[$this->routeVar] : $r;
- }
- if($this->useStrictParsing)
- throw new CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',
- array('{route}'=>$pathInfo)));
- else
- return $pathInfo;
- }
- elseif(isset($_GET[$this->routeVar]))
- return $_GET[$this->routeVar];
- elseif(isset($_POST[$this->routeVar]))
- return $_POST[$this->routeVar];
- else
- return '';
- }
- public function parsePathInfo($pathInfo)
- {
- if($pathInfo==='')
- return;
- $segs=explode('/',$pathInfo.'/');
- $n=count($segs);
- for($i=0;$i<$n-1;$i+=2)
- {
- $key=$segs[$i];
- if($key==='') continue;
- $value=$segs[$i+1];
- if(($pos=strpos($key,'['))!==false && ($m=preg_match_all('/\[(.*?)\]/',$key,$matches))>0)
- {
- $name=substr($key,0,$pos);
- for($j=$m-1;$j>=0;--$j)
- {
- if($matches[1][$j]==='')
- $value=array($value);
- else
- $value=array($matches[1][$j]=>$value);
- }
- if(isset($_GET[$name]) && is_array($_GET[$name]))
- $value=CMap::mergeArray($_GET[$name],$value);
- $_REQUEST[$name]=$_GET[$name]=$value;
- }
- else
- $_REQUEST[$key]=$_GET[$key]=$value;
- }
- }
- public function createPathInfo($params,$equal,$ampersand, $key=null)
- {
- $pairs = array();
- foreach($params as $k => $v)
- {
- if ($key!==null)
- $k = $key.'['.$k.']';
- if (is_array($v))
- $pairs[]=$this->createPathInfo($v,$equal,$ampersand, $k);
- else
- $pairs[]=urlencode($k).$equal.urlencode($v);
- }
- return implode($ampersand,$pairs);
- }
- public function removeUrlSuffix($pathInfo,$urlSuffix)
- {
- if($urlSuffix!=='' && substr($pathInfo,-strlen($urlSuffix))===$urlSuffix)
- return substr($pathInfo,0,-strlen($urlSuffix));
- else
- return $pathInfo;
- }
- public function getBaseUrl()
- {
- if($this->_baseUrl!==null)
- return $this->_baseUrl;
- else
- {
- if($this->showScriptName)
- $this->_baseUrl=Yii::app()->getRequest()->getScriptUrl();
- else
- $this->_baseUrl=Yii::app()->getRequest()->getBaseUrl();
- return $this->_baseUrl;
- }
- }
- public function setBaseUrl($value)
- {
- $this->_baseUrl=$value;
- }
- public function getUrlFormat()
- {
- return $this->_urlFormat;
- }
- public function setUrlFormat($value)
- {
- if($value===self::PATH_FORMAT || $value===self::GET_FORMAT)
- $this->_urlFormat=$value;
- else
- throw new CException(Yii::t('yii','CUrlManager.UrlFormat must be either "path" or "get".'));
- }
- }
- abstract class CBaseUrlRule extends CComponent
- {
- public $hasHostInfo=false;
- abstract public function createUrl($manager,$route,$params,$ampersand);
- abstract public function parseUrl($manager,$request,$pathInfo,$rawPathInfo);
- }
- class CUrlRule extends CBaseUrlRule
- {
- public $urlSuffix;
- public $caseSensitive;
- public $defaultParams=array();
- public $matchValue;
- public $verb;
- public $parsingOnly=false;
- public $route;
- public $references=array();
- public $routePattern;
- public $pattern;
- public $template;
- public $params=array();
- public $append;
- public $hasHostInfo;
- public function __construct($route,$pattern)
- {
- if(is_array($route))
- {
- foreach(array('urlSuffix', 'caseSensitive', 'defaultParams', 'matchValue', 'verb', 'parsingOnly') as $name)
- {
- if(isset($route[$name]))
- $this->$name=$route[$name];
- }
- if(isset($route['pattern']))
- $pattern=$route['pattern'];
- $route=$route[0];
- }
- $this->route=trim($route,'/');
- $tr2['/']=$tr['/']='\\/';
- $tr['.']='\\.';
- if(strpos($route,'<')!==false && preg_match_all('/<(\w+)>/',$route,$matches2))
- {
- foreach($matches2[1] as $name)
- $this->references[$name]="<$name>";
- }
- $this->hasHostInfo=!strncasecmp($pattern,'http://',7) || !strncasecmp($pattern,'https://',8);
- if($this->verb!==null)
- $this->verb=preg_split('/[\s,]+/',strtoupper($this->verb),-1,PREG_SPLIT_NO_EMPTY);
- if(preg_match_all('/<(\w+):?(.*?)?>/',$pattern,$matches))
- {
- $tokens=array_combine($matches[1],$matches[2]);
- foreach($tokens as $name=>$value)
- {
- if($value==='')
- $value='[^\/]+';
- $tr["<$name>"]="(?P<$name>$value)";
- if(isset($this->references[$name]))
- $tr2["<$name>"]=$tr["<$name>"];
- else
- $this->params[$name]=$value;
- }
- }
- $p=rtrim($pattern,'*');
- $this->append=$p!==$pattern;
- $p=trim($p,'/');
- $this->template=preg_replace('/<(\w+):?.*?>/','<$1>',$p);
- $this->pattern='/^'.strtr($this->template,$tr).'\/';
- if($this->append)
- $this->pattern.='/u';
- else
- $this->pattern.='$/u';
- if($this->references!==array())
- $this->routePattern='/^'.strtr($this->route,$tr2).'$/u';
- if(YII_DEBUG && @preg_match($this->pattern,'test')===false)
- throw new CException(Yii::t('yii','The URL pattern "{pattern}" for route "{route}" is not a valid regular expression.',
- array('{route}'=>$route,'{pattern}'=>$pattern)));
- }
- public function createUrl($manager,$route,$params,$ampersand)
- {
- if($this->parsingOnly)
- return false;
- if($manager->caseSensitive && $this->caseSensitive===null || $this->caseSensitive)
- $case='';
- else
- $case='i';
- $tr=array();
- if($route!==$this->route)
- {
- if($this->routePattern!==null && preg_match($this->routePattern.$case,$route,$matches))
- {
- foreach($this->references as $key=>$name)
- $tr[$name]=$matches[$key];
- }
- else
- return false;
- }
- foreach($this->defaultParams as $key=>$value)
- {
- if(isset($params[$key]))
- {
- if($params[$key]==$value)
- unset($params[$key]);
- else
- return false;
- }
- }
- foreach($this->params as $key=>$value)
- if(!isset($params[$key]))
- return false;
- if($manager->matchValue && $this->matchValue===null || $this->matchValue)
- {
- foreach($this->params as $key=>$value)
- {
- if(!preg_match('/\A'.$value.'\z/u'.$case,$params[$key]))
- return false;
- }
- }
- foreach($this->params as $key=>$value)
- {
- $tr["<$key>"]=urlencode($params[$key]);
- unset($params[$key]);
- }
- $suffix=$this->urlSuffix===null ? $manager->urlSuffix : $this->urlSuffix;
- $url=strtr($this->template,$tr);
- if($this->hasHostInfo)
- {
- $hostInfo=Yii::app()->getRequest()->getHostInfo();
- if(stripos($url,$hostInfo)===0)
- $url=substr($url,strlen($hostInfo));
- }
- if(empty($params))
- return $url!=='' ? $url.$suffix : $url;
- if($this->append)
- $url.='/'.$manager->createPathInfo($params,'/','/').$suffix;
- else
- {
- if($url!=='')
- $url.=$suffix;
- $url.='?'.$manager->createPathInfo($params,'=',$ampersand);
- }
- return $url;
- }
- public function parseUrl($manager,$request,$pathInfo,$rawPathInfo)
- {
- if($this->verb!==null && !in_array($request->getRequestType(), $this->verb, true))
- return false;
- if($manager->caseSensitive && $this->caseSensitive===null || $this->caseSensitive)
- $case='';
- else
- $case='i';
- if($this->urlSuffix!==null)
- $pathInfo=$manager->removeUrlSuffix($rawPathInfo,$this->urlSuffix);
- // URL suffix required, but not found in the requested URL
- if($manager->useStrictParsing && $pathInfo===$rawPathInfo)
- {
- $urlSuffix=$this->urlSuffix===null ? $manager->urlSuffix : $this->urlSuffix;
- if($urlSuffix!='' && $urlSuffix!=='/')
- return false;
- }
- if($this->hasHostInfo)
- $pathInfo=strtolower($request->getHostInfo()).rtrim('/'.$pathInfo,'/');
- $pathInfo.='/';
- if(preg_match($this->pattern.$case,$pathInfo,$matches))
- {
- foreach($this->defaultParams as $name=>$value)
- {
- if(!isset($_GET[$name]))
- $_REQUEST[$name]=$_GET[$name]=$value;
- }
- $tr=array();
- foreach($matches as $key=>$value)
- {
- if(isset($this->references[$key]))
- $tr[$this->references[$key]]=$value;
- elseif(isset($this->params[$key]))
- $_REQUEST[$key]=$_GET[$key]=$value;
- }
- if($pathInfo!==$matches[0]) // there're additional GET params
- $manager->parsePathInfo(ltrim(substr($pathInfo,strlen($matches[0])),'/'));
- if($this->routePattern!==null)
- return strtr($this->route,$tr);
- else
- return $this->route;
- }
- else
- return false;
- }
- }
- abstract class CBaseController extends CComponent
- {
- private $_widgetStack=array();
- abstract public function getViewFile($viewName);
- public function renderFile($viewFile,$data=null,$return=false)
- {
- $widgetCount=count($this->_widgetStack);
- if(($renderer=Yii::app()->getViewRenderer())!==null && $renderer->fileExtension==='.'.CFileHelper::getExtension($viewFile))
- $content=$renderer->renderFile($this,$viewFile,$data,$return);
- else
- $content=$this->renderInternal($viewFile,$data,$return);
- if(count($this->_widgetStack)===$widgetCount)
- return $content;
- else
- {
- $widget=end($this->_widgetStack);
- throw new CException(Yii::t('yii','{controller} contains improperly nested widget tags in its view "{view}". A {widget} widget does not have an endWidget() call.',
- array('{controller}'=>get_class($this), '{view}'=>$viewFile, '{widget}'=>get_class($widget))));
- }
- }
- public function renderInternal($_viewFile_,$_data_=null,$_return_=false)
- {
- // we use special variable names here to avoid conflict when extracting data
- if(is_array($_data_))
- extract($_data_,EXTR_PREFIX_SAME,'data');
- else
- $data=$_data_;
- if($_return_)
- {
- ob_start();
- ob_implicit_flush(false);
- require($_viewFile_);
- return ob_get_clean();
- }
- else
- require($_viewFile_);
- }
- public function createWidget($className,$properties=array())
- {
- $widget=Yii::app()->getWidgetFactory()->createWidget($this,$className,$properties);
- $widget->init();
- return $widget;
- }
- public function widget($className,$properties=array(),$captureOutput=false)
- {
- if($captureOutput)
- {
- ob_start();
- ob_implicit_flush(false);
- try
- {
- $widget=$this->createWidget($className,$properties);
- $widget->run();
- }
- catch(Exception $e)
- {
- ob_end_clean();
- throw $e;
- }
- return ob_get_clean();
- }
- else
- {
- $widget=$this->createWidget($className,$properties);
- $widget->run();
- return $widget;
- }
- }
- public function beginWidget($className,$properties=array())
- {
- $widget=$this->createWidget($className,$properties);
- $this->_widgetStack[]=$widget;
- return $widget;
- }
- public function endWidget($id='')
- {
- if(($widget=array_pop($this->_widgetStack))!==null)
- {
- $widget->run();
- return $widget;
- }
- else
- throw new CException(Yii::t('yii','{controller} has an extra endWidget({id}) call in its view.',
- array('{controller}'=>get_class($this),'{id}'=>$id)));
- }
- public function beginClip($id,$properties=array())
- {
- $properties['id']=$id;
- $this->beginWidget('CClipWidget',$properties);
- }
- public function endClip()
- {
- $this->endWidget('CClipWidget');
- }
- public function beginCache($id,$properties=array())
- {
- $properties['id']=$id;
- $cache=$this->beginWidget('COutputCache',$properties);
- if($cache->getIsContentCached())
- {
- $this->endCache();
- return false;
- }
- else
- return true;
- }
- public function endCache()
- {
- $this->endWidget('COutputCache');
- }
- public function beginContent($view=null,$data=array())
- {
- $this->beginWidget('CContentDecorator',array('view'=>$view, 'data'=>$data));
- }
- public function endContent()
- {
- $this->endWidget('CContentDecorator');
- }
- }
- class CController extends CBaseController
- {
- const STATE_INPUT_NAME='YII_PAGE_STATE';
- public $layout;
- public $defaultAction='index';
- private $_id;
- private $_action;
- private $_pageTitle;
- private $_cachingStack;
- private $_clips;
- private $_dynamicOutput;
- private $_pageStates;
- private $_module;
- public function __construct($id,$module=null)
- {
- $this->_id=$id;
- $this->_module=$module;
- $this->attachBehaviors($this->behaviors());
- }
- public function init()
- {
- }
- public function filters()
- {
- return array();
- }
- public function actions()
- {
- return array();
- }
- public function behaviors()
- {
- return array();
- }
- public function accessRules()
- {
- return array();
- }
- public function run($actionID)
- {
- if(($action=$this->createAction($actionID))!==null)
- {
- if(($parent=$this->getModule())===null)
- $parent=Yii::app();
- if($parent->beforeControllerAction($this,$action))
- {
- $this->runActionWithFilters($action,$this->filters());
- $parent->afterControllerAction($this,$action);
- }
- }
- else
- $this->missingAction($actionID);
- }
- public function runActionWithFilters($action,$filters)
- {
- if(empty($filters))
- $this->runAction($action);
- else
- {
- $priorAction=$this->_action;
- $this->_action=$action;
- CFilterChain::create($this,$action,$filters)->run();
- $this->_action=$priorAction;
- }
- }
- public function runAction($action)
- {
- $priorAction=$this->_action;
- $this->_action=$action;
- if($this->beforeAction($action))
- {
- if($action->runWithParams($this->getActionParams())===false)
- $this->invalidActionParams($action);
- else
- $this->afterAction($action);
- }
- $this->_action=$priorAction;
- }
- public function getActionParams()
- {
- return $_GET;
- }
- public function invalidActionParams($action)
- {
- throw new CHttpException(400,Yii::t('yii','Your request is invalid.'));
- }
- public function processOutput($output)
- {
- Yii::app()->getClientScript()->render($output);
- // if using page caching, we should delay dynamic output replacement
- if($this->_dynamicOutput!==null && $this->isCachingStackEmpty())
- {
- $output=$this->processDynamicOutput($output);
- $this->_dynamicOutput=null;
- }
- if($this->_pageStates===null)
- $this->_pageStates=$this->loadPageStates();
- if(!empty($this->_pageStates))
- $this->savePageStates($this->_pageStates,$output);
- return $output;
- }
- public function processDynamicOutput($output)
- {
- if($this->_dynamicOutput)
- {
- $output=preg_replace_callback('/<###dynamic-(\d+)###>/',array($this,'replaceDynamicOutput'),$output);
- }
- return $output;
- }
- protected function replaceDynamicOutput($matches)
- {
- $content=$matches[0];
- if(isset($this->_dynamicOutput[$matches[1]]))
- {
- $content=$this->_dynamicOutput[$matches[1]];
- $this->_dynamicOutput[$matches[1]]=null;
- }
- return $content;
- }
- public function createAction($actionID)
- {
- if($actionID==='')
- $actionID=$this->defaultAction;
- if(method_exists($this,'action'.$actionID) && strcasecmp($actionID,'s')) // we have actions method
- return new CInlineAction($this,$actionID);
- else
- {
- $action=$this->createActionFromMap($this->actions(),$actionID,$actionID);
- if($action!==null && !method_exists($action,'run'))
- throw new CException(Yii::t('yii', 'Action class {class} must implement the "run" method.', array('{class}'=>get_class($action))));
- return $action;
- }
- }
- protected function createActionFromMap($actionMap,$actionID,$requestActionID,$config=array())
- {
- if(($pos=strpos($actionID,'.'))===false && isset($actionMap[$actionID]))
- {
- $baseConfig=is_array($actionMap[$actionID]) ? $actionMap[$actionID] : array('class'=>$actionMap[$actionID]);
- return Yii::createComponent(empty($config)?$baseConfig:array_merge($baseConfig,$config),$this,$requestActionID);
- }
- elseif($pos===false)
- return null;
- // the action is defined in a provider
- $prefix=substr($actionID,0,$pos+1);
- if(!isset($actionMap[$prefix]))
- return null;
- $actionID=(string)substr($actionID,$pos+1);
- $provider=$actionMap[$prefix];
- if(is_string($provider))
- $providerType=$provider;
- elseif(is_array($provider) && isset($provider['class']))
- {
- $providerType=$provider['class'];
- if(isset($provider[$actionID]))
- {
- if(is_string($provider[$actionID]))
- $config=array_merge(array('class'=>$provider[$actionID]),$config);
- else
- $config=array_merge($provider[$actionID],$config);
- }
- }
- else
- throw new CException(Yii::t('yii','Object configuration must be an array containing a "class" element.'));
- $class=Yii::import($providerType,true);
- $map=call_user_func(array($class,'actions'));
- return $this->createActionFromMap($map,$actionID,$requestActionID,$config);
- }
- public function missingAction($actionID)
- {
- throw new CHttpException(404,Yii::t('yii','The system is unable to find the requested action "{action}".',
- array('{action}'=>$actionID==''?$this->defaultAction:$actionID)));
- }
- public function getAction()
- {
- return $this->_action;
- }
- public function setAction($value)
- {
- $this->_action=$value;
- }
- public function getId()
- {
- return $this->_id;
- }
- public function getUniqueId()
- {
- return $this->_module ? $this->_module->getId().'/'.$this->_id : $this->_id;
- }
- public function getRoute()
- {
- if(($action=$this->getAction())!==null)
- return $this->getUniqueId().'/'.$action->getId();
- else
- return $this->getUniqueId();
- }
- public function getModule()
- {
- return $this->_module;
- }
- public function getViewPath()
- {
- if(($module=$this->getModule())===null)
- $module=Yii::app();
- return $module->getViewPath().DIRECTORY_SEPARATOR.$this->getId();
- }
- public function getViewFile($viewName)
- {
- if(($theme=Yii::app()->getTheme())!==null && ($viewFile=$theme->getViewFile($this,$viewName))!==false)
- return $viewFile;
- $moduleViewPath=$basePath=Yii::app()->getViewPath();
- if(($module=$this->getModule())!==null)
- $moduleViewPath=$module->getViewPath();
- return $this->resolveViewFile($viewName,$this->getViewPath(),$basePath,$moduleViewPath);
- }
- public function getLayoutFile($layoutName)
- {
- if($layoutName===false)
- return false;
- if(($theme=Yii::app()->getTheme())!==null && ($layoutFile=$theme->getLayoutFile($this,$layoutName))!==false)
- return $layoutFile;
- if(empty($layoutName))
- {
- $module=$this->getModule();
- while($module!==null)
- {
- if($module->layout===false)
- return false;
- if(!empty($module->layout))
- break;
- $module=$module->getParentModule();
- }
- if($module===null)
- $module=Yii::app();
- $layoutName=$module->layout;
- }
- elseif(($module=$this->getModule())===null)
- $module=Yii::app();
- return $this->resolveViewFile($layoutName,$module->getLayoutPath(),Yii::app()->getViewPath(),$module->getViewPath());
- }
- public function resolveViewFile($viewName,$viewPath,$basePath,$moduleViewPath=null)
- {
- if(empty($viewName))
- return false;
- if($moduleViewPath===null)
- $moduleViewPath=$basePath;
- if(($renderer=Yii::app()->getViewRenderer())!==null)
- $extension=$renderer->fileExtension;
- else
- $extension='.php';
- if($viewName[0]==='/')
- {
- if(strncmp($viewName,'//',2)===0)
- $viewFile=$basePath.$viewName;
- else
- $viewFile=$moduleViewPath.$viewName;
- }
- elseif(strpos($viewName,'.'))
- $viewFile=Yii::getPathOfAlias($viewName);
- else
- $viewFile=$viewPath.DIRECTORY_SEPARATOR.$viewName;
- if(is_file($viewFile.$extension))
- return Yii::app()->findLocalizedFile($viewFile.$extension);
- elseif($extension!=='.php' && is_file($viewFile.'.php'))
- return Yii::app()->findLocalizedFile($viewFile.'.php');
- else
- return false;
- }
- public function getClips()
- {
- if($this->_clips!==null)
- return $this->_clips;
- else
- return $this->_clips=new CMap;
- }
- public function forward($route,$exit=true)
- {
- if(strpos($route,'/')===false)
- $this->run($route);
- else
- {
- if($route[0]!=='/' && ($module=$this->getModule())!==null)
- $route=$module->getId().'/'.$route;
- Yii::app()->runController($route);
- }
- if($exit)
- Yii::app()->end();
- }
- public function render($view,$data=null,$return=false)
- {
- if($this->beforeRender($view))
- {
- $output=$this->renderPartial($view,$data,true);
- if(($layoutFile=$this->getLayoutFile($this->layout))!==false)
- $output=$this->renderFile($layoutFile,array('content'=>$output),true);
- $this->afterRender($view,$output);
- $output=$this->processOutput($output);
- if($return)
- return $output;
- else
- echo $output;
- }
- }
- protected function beforeRender($view)
- {
- return true;
- }
- protected function afterRender($view, &$output)
- {
- }
- public function renderText($text,$return=false)
- {
- if(($layoutFile=$this->getLayoutFile($this->layout))!==false)
- $text=$this->renderFile($layoutFile,array('content'=>$text),true);
- $text=$this->processOutput($text);
- if($return)
- return $text;
- else
- echo $text;
- }
- public function renderPartial($view,$data=null,$return=false,$processOutput=false)
- {
- if(($viewFile=$this->getViewFile($view))!==false)
- {
- $output=$this->renderFile($viewFile,$data,true);
- if($processOutput)
- $output=$this->processOutput($output);
- if($return)
- return $output;
- else
- echo $output;
- }
- else
- throw new CException(Yii::t('yii','{controller} cannot find the requested view "{view}".',
- array('{controller}'=>get_class($this), '{view}'=>$view)));
- }
- public function renderClip($name,$params=array(),$return=false)
- {
- $text=isset($this->clips[$name]) ? strtr($this->clips[$name], $params) : '';
- if($return)
- return $text;
- else
- echo $text;
- }
- public function renderDynamic($callback)
- {
- $n=count($this->_dynamicOutput);
- echo "<###dynamic-$n###>";
- $params=func_get_args();
- array_shift($params);
- $this->renderDynamicInternal($callback,$params);
- }
- public function renderDynamicInternal($callback,$params)
- {
- $this->recordCachingAction('','renderDynamicInternal',array($callback,$params));
- if(is_string($callback) && method_exists($this,$callback))
- $callback=array($this,$callback);
- $this->_dynamicOutput[]=call_user_func_array($callback,$params);
- }
- public function createUrl($route,$params=array(),$ampersand='&')
- {
- if($route==='')
- $route=$this->getId().'/'.$this->getAction()->getId();
- elseif(strpos($route,'/')===false)
- $route=$this->getId().'/'.$route;
- if($route[0]!=='/' && ($module=$this->getModule())!==null)
- $route=$module->getId().'/'.$route;
- return Yii::app()->createUrl(trim($route,'/'),$params,$ampersand);
- }
- public function createAbsoluteUrl($route,$params=array(),$schema='',$ampersand='&')
- {
- $url=$this->createUrl($route,$params,$ampersand);
- if(strpos($url,'http')===0)
- return $url;
- else
- return Yii::app()->getRequest()->getHostInfo($schema).$url;
- }
- public function getPageTitle()
- {
- if($this->_pageTitle!==null)
- return $this->_pageTitle;
- else
- {
- $name=ucfirst(basename($this->getId()));
- if($this->getAction()!==null && strcasecmp($this->getAction()->getId(),$this->defaultAction))
- return $this->_pageTitle=Yii::app()->name.' - '.ucfirst($this->getAction()->getId()).' '.$name;
- else
- return $this->_pageTitle=Yii::app()->name.' - '.$name;
- }
- }
- public function setPageTitle($value)
- {
- $this->_pageTitle=$value;
- }
- public function redirect($url,$terminate=true,$statusCode=302)
- {
- if(is_array($url))
- {
- $route=isset($url[0]) ? $url[0] : '';
- $url=$this->createUrl($route,array_splice($url,1));
- }
- Yii::app()->getRequest()->redirect($url,$terminate,$statusCode);
- }
- public function refresh($terminate=true,$anchor='')
- {
- $this->redirect(Yii::app()->getRequest()->getUrl().$anchor,$terminate);
- }
- public function recordCachingAction($context,$method,$params)
- {
- if($this->_cachingStack) // record only when there is an active output cache
- {
- foreach($this->_cachingStack as $cache)
- $cache->recordAction($context,$method,$params);
- }
- }
- public function getCachingStack($createIfNull=true)
- {
- if(!$this->_cachingStack)
- $this->_cachingStack=new CStack;
- return $this->_cachingStack;
- }
- public function isCachingStackEmpty()
- {
- return $this->_cachingStack===null || !$this->_cachingStack->getCount();
- }
- protected function beforeAction($action)
- {
- return true;
- }
- protected function afterAction($action)
- {
- }
- public function filterPostOnly($filterChain)
- {
- if(Yii::app()->getRequest()->getIsPostRequest())
- $filterChain->run();
- else
- throw new CHttpException(400,Yii::t('yii','Your request is invalid.'));
- }
- public function filterAjaxOnly($filterChain)
- {
- if(Yii::app()->getRequest()->getIsAjaxRequest())
- $filterChain->run();
- else
- throw new CHttpException(400,Yii::t('yii','Your request is invalid.'));
- }
- public function filterAccessControl($filterChain)
- {
- $filter=new CAccessControlFilter;
- $filter->setRules($this->accessRules());
- $filter->filter($filterChain);
- }
- public function getPageState($name,$defaultValue=null)
- {
- if($this->_pageStates===null)
- $this->_pageStates=$this->loadPageStates();
- return isset($this->_pageStates[$name])?$this->_pageStates[$name]:$defaultValue;
- }
- public function setPageState($name,$value,$defaultValue=null)
- {
- if($this->_pageStates===null)
- $this->_pageStates=$this->loadPageStates();
- if($value===$defaultValue)
- unset($this->_pageStates[$name]);
- else
- $this->_pageStates[$name]=$value;
- $params=func_get_args();
- $this->recordCachingAction('','setPageState',$params);
- }
- public function clearPageStates()
- {
- $this->_pageStates=array();
- }
- protected function loadPageStates()
- {
- if(!empty($_POST[self::STATE_INPUT_NAME]))
- {
- if(($data=base64_decode($_POST[self::STATE_INPUT_NAME]))!==false)
- {
- if(extension_loaded('zlib'))
- $data=@gzuncompress($data);
- if(($data=Yii::app()->getSecurityManager()->validateData($data))!==false)
- return unserialize($data);
- }
- }
- return array();
- }
- protected function savePageStates($states,&$output)
- {
- $data=Yii::app()->getSecurityManager()->hashData(serialize($states));
- if(extension_loaded('zlib'))
- $data=gzcompress($data);
- $value=base64_encode($data);
- $output=str_replace(CHtml::pageStateField(''),CHtml::pageStateField($value),$output);
- }
- }
- abstract class CAction extends CComponent implements IAction
- {
- private $_id;
- private $_controller;
- public function __construct($controller,$id)
- {
- $this->_controller=$controller;
- $this->_id=$id;
- }
- public function getController()
- {
- return $this->_controller;
- }
- public function getId()
- {
- return $this->_id;
- }
- public function runWithParams($params)
- {
- $method=new ReflectionMethod($this, 'run');
- if($method->getNumberOfParameters()>0)
- return $this->runWithParamsInternal($this, $method, $params);
- $this->run();
- return true;
- }
- protected function runWithParamsInternal($object, $method, $params)
- {
- $ps=array();
- foreach($method->getParameters() as $i=>$param)
- {
- $name=$param->getName();
- if(isset($params[$name]))
- {
- if($param->isArray())
- $ps[]=is_array($params[$name]) ? $params[$name] : array($params[$name]);
- elseif(!is_array($params[$name]))
- $ps[]=$params[$name];
- else
- return false;
- }
- elseif($param->isDefaultValueAvailable())
- $ps[]=$param->getDefaultValue();
- else
- return false;
- }
- $method->invokeArgs($object,$ps);
- return true;
- }
- }
- class CInlineAction extends CAction
- {
- public function run()
- {
- $method='action'.$this->getId();
- $this->getController()->$method();
- }
- public function runWithParams($params)
- {
- $methodName='action'.$this->getId();
- $controller=$this->getController();
- $method=new ReflectionMethod($controller, $methodName);
- if($method->getNumberOfParameters()>0)
- return $this->runWithParamsInternal($controller, $method, $params);
- $controller->$methodName();
- return true;
- }
- }
- class CWebUser extends CApplicationComponent implements IWebUser
- {
- const FLASH_KEY_PREFIX='Yii.CWebUser.flash.';
- const FLASH_COUNTERS='Yii.CWebUser.flashcounters';
- const STATES_VAR='__states';
- const AUTH_TIMEOUT_VAR='__timeout';
- const AUTH_ABSOLUTE_TIMEOUT_VAR='__absolute_timeout';
- public $allowAutoLogin=false;
- public $guestName='Guest';
- public $loginUrl=array('/site/login');
- public $identityCookie;
- public $authTimeout;
- public $absoluteAuthTimeout;
- public $autoRenewCookie=false;
- public $autoUpdateFlash=true;
- public $loginRequiredAjaxResponse;
- private $_keyPrefix;
- private $_access=array();
- public function __get($name)
- {
- if($this->hasState($name))
- return $this->getState($name);
- else
- return parent::__get($name);
- }
- public function __set($name,$value)
- {
- if($this->hasState($name))
- $this->setState($name,$value);
- else
- parent::__set($name,$value);
- }
- public function __isset($name)
- {
- if($this->hasState($name))
- return $this->getState($name)!==null;
- else
- return parent::__isset($name);
- }
- public function __unset($name)
- {
- if($this->hasState($name))
- $this->setState($name,null);
- else
- parent::__unset($name);
- }
- public function init()
- {
- parent::init();
- Yii::app()->getSession()->open();
- if($this->getIsGuest() && $this->allowAutoLogin)
- $this->restoreFromCookie();
- elseif($this->autoRenewCookie && $this->allowAutoLogin)
- $this->renewCookie();
- if($this->autoUpdateFlash)
- $this->updateFlash();
- $this->updateAuthStatus();
- }
- public function login($identity,$duration=0)
- {
- $id=$identity->getId();
- $states=$identity->getPersistentStates();
- if($this->beforeLogin($id,$states,false))
- {
- $this->changeIdentity($id,$identity->getName(),$states);
- if($duration>0)
- {
- if($this->allowAutoLogin)
- $this->saveToCookie($duration);
- else
- throw new CException(Yii::t('yii','{class}.allowAutoLogin must be set true in order to use cookie-based authentication.',
- array('{class}'=>get_class($this))));
- }
- if ($this->absoluteAuthTimeout)
- $this->setState(self::AUTH_ABSOLUTE_TIMEOUT_VAR, time()+$this->absoluteAuthTimeout);
- $this->afterLogin(false);
- }
- return !$this->getIsGuest();
- }
- public function logout($destroySession=true)
- {
- if($this->beforeLogout())
- {
- if($this->allowAutoLogin)
- {
- Yii::app()->getRequest()->getCookies()->remove($this->getStateKeyPrefix());
- if($this->identityCookie!==null)
- {
- $cookie=$this->createIdentityCookie($this->getStateKeyPrefix());
- $cookie->value=null;
- $cookie->expire=0;
- Yii::app()->getRequest()->getCookies()->add($cookie->name,$cookie);
- }
- }
- if($destroySession)
- Yii::app()->getSession()->destroy();
- else
- $this->clearStates();
- $this->_access=array();
- $this->afterLogout();
- }
- }
- public function getIsGuest()
- {
- return $this->getState('__id')===null;
- }
- public function getId()
- {
- return $this->getState('__id');
- }
- public function setId($value)
- {
- $this->setState('__id',$value);
- }
- public function getName()
- {
- if(($name=$this->getState('__name'))!==null)
- return $name;
- else
- return $this->guestName;
- }
- public function setName($value)
- {
- $this->setState('__name',$value);
- }
- public function getReturnUrl($defaultUrl=null)
- {
- if($defaultUrl===null)
- {
- $defaultReturnUrl=Yii::app()->getUrlManager()->showScriptName ? Yii::app()->getRequest()->getScriptUrl() : Yii::app()->getRequest()->getBaseUrl().'/';
- }
- else
- {
- $defaultReturnUrl=CHtml::normalizeUrl($defaultUrl);
- }
- return $this->getState('__returnUrl',$defaultReturnUrl);
- }
- public function setReturnUrl($value)
- {
- $this->setState('__returnUrl',$value);
- }
- public function loginRequired()
- {
- $app=Yii::app();
- $request=$app->getRequest();
- if(!$request->getIsAjaxRequest())
- {
- $this->setReturnUrl($request->getUrl());
- if(($url=$this->loginUrl)!==null)
- {
- if(is_array($url))
- {
- $route=isset($url[0]) ? $url[0] : $app->defaultController;
- $url=$app->createUrl($route,array_splice($url,1));
- }
- $request->redirect($url);
- }
- }
- elseif(isset($this->loginRequiredAjaxResponse))
- {
- echo $this->loginRequiredAjaxResponse;
- Yii::app()->end();
- }
- throw new CHttpException(403,Yii::t('yii','Login Required'));
- }
- protected function beforeLogin($id,$states,$fromCookie)
- {
- return true;
- }
- protected function afterLogin($fromCookie)
- {
- }
- protected function beforeLogout()
- {
- return true;
- }
- protected function afterLogout()
- {
- }
- protected function restoreFromCookie()
- {
- $app=Yii::app();
- $request=$app->getRequest();
- $cookie=$request->getCookies()->itemAt($this->getStateKeyPrefix());
- if($cookie && !empty($cookie->value) && is_string($cookie->value) && ($data=$app->getSecurityManager()->validateData($cookie->value))!==false)
- {
- $data=@unserialize($data);
- if(is_array($data) && isset($data[0],$data[1],$data[2],$data[3]))
- {
- list($id,$name,$duration,$states)=$data;
- if($this->beforeLogin($id,$states,true))
- {
- $this->changeIdentity($id,$name,$states);
- if($this->autoRenewCookie)
- {
- $this->saveToCookie($duration);
- }
- $this->afterLogin(true);
- }
- }
- }
- }
- protected function renewCookie()
- {
- $request=Yii::app()->getRequest();
- $cookies=$request->getCookies();
- $cookie=$cookies->itemAt($this->getStateKeyPrefix());
- if($cookie && !empty($cookie->value) && ($data=Yii::app()->getSecurityManager()->validateData($cookie->value))!==false)
- {
- $data=@unserialize($data);
- if(is_array($data) && isset($data[0],$data[1],$data[2],$data[3]))
- {
- $this->saveToCookie($data[2]);
- }
- }
- }
- protected function saveToCookie($duration)
- {
- $app=Yii::app();
- $cookie=$this->createIdentityCookie($this->getStateKeyPrefix());
- $cookie->expire=time()+$duration;
- $data=array(
- $this->getId(),
- $this->getName(),
- $duration,
- $this->saveIdentityStates(),
- );
- $cookie->value=$app->getSecurityManager()->hashData(serialize($data));
- $app->getRequest()->getCookies()->add($cookie->name,$cookie);
- }
- protected function createIdentityCookie($name)
- {
- $cookie=new CHttpCookie($name,'');
- if(is_array($this->identityCookie))
- {
- foreach($this->identityCookie as $name=>$value)
- $cookie->$name=$value;
- }
- return $cookie;
- }
- public function getStateKeyPrefix()
- {
- if($this->_keyPrefix!==null)
- return $this->_keyPrefix;
- else
- return $this->_keyPrefix=md5('Yii.'.get_class($this).'.'.Yii::app()->getId());
- }
- public function setStateKeyPrefix($value)
- {
- $this->_keyPrefix=$value;
- }
- public function getState($key,$defaultValue=null)
- {
- $key=$this->getStateKeyPrefix().$key;
- return isset($_SESSION[$key]) ? $_SESSION[$key] : $defaultValue;
- }
- public function setState($key,$value,$defaultValue=null)
- {
- $key=$this->getStateKeyPrefix().$key;
- if($value===$defaultValue)
- unset($_SESSION[$key]);
- else
- $_SESSION[$key]=$value;
- }
- public function hasState($key)
- {
- $key=$this->getStateKeyPrefix().$key;
- return isset($_SESSION[$key]);
- }
- public function clearStates()
- {
- $keys=array_keys($_SESSION);
- $prefix=$this->getStateKeyPrefix();
- $n=strlen($prefix);
- foreach($keys as $key)
- {
- if(!strncmp($key,$prefix,$n))
- unset($_SESSION[$key]);
- }
- }
- public function getFlashes($delete=true)
- {
- $flashes=array();
- $prefix=$this->getStateKeyPrefix().self::FLASH_KEY_PREFIX;
- $keys=array_keys($_SESSION);
- $n=strlen($prefix);
- foreach($keys as $key)
- {
- if(!strncmp($key,$prefix,$n))
- {
- $flashes[substr($key,$n)]=$_SESSION[$key];
- if($delete)
- unset($_SESSION[$key]);
- }
- }
- if($delete)
- $this->setState(self::FLASH_COUNTERS,array());
- return $flashes;
- }
- public function getFlash($key,$defaultValue=null,$delete=true)
- {
- $value=$this->getState(self::FLASH_KEY_PREFIX.$key,$defaultValue);
- if($delete)
- $this->setFlash($key,null);
- return $value;
- }
- public function setFlash($key,$value,$defaultValue=null)
- {
- $this->setState(self::FLASH_KEY_PREFIX.$key,$value,$defaultValue);
- $counters=$this->getState(self::FLASH_COUNTERS,array());
- if($value===$defaultValue)
- unset($counters[$key]);
- else
- $counters[$key]=0;
- $this->setState(self::FLASH_COUNTERS,$counters,array());
- }
- public function hasFlash($key)
- {
- return $this->getFlash($key, null, false)!==null;
- }
- protected function changeIdentity($id,$name,$states)
- {
- Yii::app()->getSession()->regenerateID(true);
- $this->setId($id);
- $this->setName($name);
- $this->loadIdentityStates($states);
- }
- protected function saveIdentityStates()
- {
- $states=array();
- foreach($this->getState(self::STATES_VAR,array()) as $name=>$dummy)
- $states[$name]=$this->getState($name);
- return $states;
- }
- protected function loadIdentityStates($states)
- {
- $names=array();
- if(is_array($states))
- {
- foreach($states as $name=>$value)
- {
- $this->setState($name,$value);
- $names[$name]=true;
- }
- }
- $this->setState(self::STATES_VAR,$names);
- }
- protected function updateFlash()
- {
- $counters=$this->getState(self::FLASH_COUNTERS);
- if(!is_array($counters))
- return;
- foreach($counters as $key=>$count)
- {
- if($count)
- {
- unset($counters[$key]);
- $this->setState(self::FLASH_KEY_PREFIX.$key,null);
- }
- else
- $counters[$key]++;
- }
- $this->setState(self::FLASH_COUNTERS,$counters,array());
- }
- protected function updateAuthStatus()
- {
- if(($this->authTimeout!==null || $this->absoluteAuthTimeout!==null) && !$this->getIsGuest())
- {
- $expires=$this->getState(self::AUTH_TIMEOUT_VAR);
- $expiresAbsolute=$this->getState(self::AUTH_ABSOLUTE_TIMEOUT_VAR);
- if ($expires!==null && $expires < time() || $expiresAbsolute!==null && $expiresAbsolute < time())
- $this->logout(false);
- else
- $this->setState(self::AUTH_TIMEOUT_VAR,time()+$this->authTimeout);
- }
- }
- public function checkAccess($operation,$params=array(),$allowCaching=true)
- {
- if($allowCaching && $params===array() && isset($this->_access[$operation]))
- return $this->_access[$operation];
- $access=Yii::app()->getAuthManager()->checkAccess($operation,$this->getId(),$params);
- if($allowCaching && $params===array())
- $this->_access[$operation]=$access;
- return $access;
- }
- }
- class CHttpSession extends CApplicationComponent implements IteratorAggregate,ArrayAccess,Countable
- {
- public $autoStart=true;
- public function init()
- {
- parent::init();
- if($this->autoStart)
- $this->open();
- register_shutdown_function(array($this,'close'));
- }
- public function getUseCustomStorage()
- {
- return false;
- }
- public function open()
- {
- if($this->getUseCustomStorage())
- @session_set_save_handler(array($this,'openSession'),array($this,'closeSession'),array($this,'readSession'),array($this,'writeSession'),array($this,'destroySession'),array($this,'gcSession'));
- @session_start();
- if(YII_DEBUG && session_id()=='')
- {
- $message=Yii::t('yii','Failed to start session.');
- if(function_exists('error_get_last'))
- {
- $error=error_get_last();
- if(isset($error['message']))
- $message=$error['message'];
- }
- Yii::log($message, CLogger::LEVEL_WARNING, 'system.web.CHttpSession');
- }
- }
- public function close()
- {
- if(session_id()!=='')
- @session_write_close();
- }
- public function destroy()
- {
- if(session_id()!=='')
- {
- @session_unset();
- @session_destroy();
- }
- }
- public function getIsStarted()
- {
- return session_id()!=='';
- }
- public function getSessionID()
- {
- return session_id();
- }
- public function setSessionID($value)
- {
- session_id($value);
- }
- public function regenerateID($deleteOldSession=false)
- {
- if($this->getIsStarted())
- session_regenerate_id($deleteOldSession);
- }
- public function getSessionName()
- {
- return session_name();
- }
- public function setSessionName($value)
- {
- session_name($value);
- }
- public function getSavePath()
- {
- return session_save_path();
- }
- public function setSavePath($value)
- {
- if(is_dir($value))
- session_save_path($value);
- else
- throw new CException(Yii::t('yii','CHttpSession.savePath "{path}" is not a valid directory.',
- array('{path}'=>$value)));
- }
- public function getCookieParams()
- {
- return session_get_cookie_params();
- }
- public function setCookieParams($value)
- {
- $data=session_get_cookie_params();
- extract($data);
- extract($value);
- if(isset($httponly))
- session_set_cookie_params($lifetime,$path,$domain,$secure,$httponly);
- else
- session_set_cookie_params($lifetime,$path,$domain,$secure);
- }
- public function getCookieMode()
- {
- if(ini_get('session.use_cookies')==='0')
- return 'none';
- elseif(ini_get('session.use_only_cookies')==='0')
- return 'allow';
- else
- return 'only';
- }
- public function setCookieMode($value)
- {
- if($value==='none')
- {
- ini_set('session.use_cookies','0');
- ini_set('session.use_only_cookies','0');
- }
- elseif($value==='allow')
- {
- ini_set('session.use_cookies','1');
- ini_set('session.use_only_cookies','0');
- }
- elseif($value==='only')
- {
- ini_set('session.use_cookies','1');
- ini_set('session.use_only_cookies','1');
- }
- else
- throw new CException(Yii::t('yii','CHttpSession.cookieMode can only be "none", "allow" or "only".'));
- }
- public function getGCProbability()
- {
- return (float)(ini_get('session.gc_probability')/ini_get('session.gc_divisor')*100);
- }
- public function setGCProbability($value)
- {
- if($value>=0 && $value<=100)
- {
- // percent * 21474837 / 2147483647 ≈ percent * 0.01
- ini_set('session.gc_probability',floor($value*21474836.47));
- ini_set('session.gc_divisor',2147483647);
- }
- else
- throw new CException(Yii::t('yii','CHttpSession.gcProbability "{value}" is invalid. It must be a float between 0 and 100.',
- array('{value}'=>$value)));
- }
- public function getUseTransparentSessionID()
- {
- return ini_get('session.use_trans_sid')==1;
- }
- public function setUseTransparentSessionID($value)
- {
- ini_set('session.use_trans_sid',$value?'1':'0');
- }
- public function getTimeout()
- {
- return (int)ini_get('session.gc_maxlifetime');
- }
- public function setTimeout($value)
- {
- ini_set('session.gc_maxlifetime',$value);
- }
- public function openSession($savePath,$sessionName)
- {
- return true;
- }
- public function closeSession()
- {
- return true;
- }
- public function readSession($id)
- {
- return '';
- }
- public function writeSession($id,$data)
- {
- return true;
- }
- public function destroySession($id)
- {
- return true;
- }
- public function gcSession($maxLifetime)
- {
- return true;
- }
- //------ The following methods enable CHttpSession to be CMap-like -----
- public function getIterator()
- {
- return new CHttpSessionIterator;
- }
- public function getCount()
- {
- return count($_SESSION);
- }
- public function count()
- {
- return $this->getCount();
- }
- public function getKeys()
- {
- return array_keys($_SESSION);
- }
- public function get($key,$defaultValue=null)
- {
- return isset($_SESSION[$key]) ? $_SESSION[$key] : $defaultValue;
- }
- public function itemAt($key)
- {
- return isset($_SESSION[$key]) ? $_SESSION[$key] : null;
- }
- public function add($key,$value)
- {
- $_SESSION[$key]=$value;
- }
- public function remove($key)
- {
- if(isset($_SESSION[$key]))
- {
- $value=$_SESSION[$key];
- unset($_SESSION[$key]);
- return $value;
- }
- else
- return null;
- }
- public function clear()
- {
- foreach(array_keys($_SESSION) as $key)
- unset($_SESSION[$key]);
- }
- public function contains($key)
- {
- return isset($_SESSION[$key]);
- }
- public function toArray()
- {
- return $_SESSION;
- }
- public function offsetExists($offset)
- {
- return isset($_SESSION[$offset]);
- }
- public function offsetGet($offset)
- {
- return isset($_SESSION[$offset]) ? $_SESSION[$offset] : null;
- }
- public function offsetSet($offset,$item)
- {
- $_SESSION[$offset]=$item;
- }
- public function offsetUnset($offset)
- {
- unset($_SESSION[$offset]);
- }
- }
- class CHtml
- {
- const ID_PREFIX='yt';
- public static $errorSummaryCss='errorSummary';
- public static $errorMessageCss='errorMessage';
- public static $errorCss='error';
- public static $errorContainerTag='div';
- public static $requiredCss='required';
- public static $beforeRequiredLabel='';
- public static $afterRequiredLabel=' <span class="required">*</span>';
- public static $count=0;
- public static $liveEvents=true;
- public static $closeSingleTags=true;
- public static $renderSpecialAttributesValue=true;
- private static $_modelNameConverter;
- public static function encode($text)
- {
- return htmlspecialchars($text,ENT_QUOTES,Yii::app()->charset);
- }
- public static function decode($text)
- {
- return htmlspecialchars_decode($text,ENT_QUOTES);
- }
- public static function encodeArray($data)
- {
- $d=array();
- foreach($data as $key=>$value)
- {
- if(is_string($key))
- $key=htmlspecialchars($key,ENT_QUOTES,Yii::app()->charset);
- if(is_string($value))
- $value=htmlspecialchars($value,ENT_QUOTES,Yii::app()->charset);
- elseif(is_array($value))
- $value=self::encodeArray($value);
- $d[$key]=$value;
- }
- return $d;
- }
- public static function tag($tag,$htmlOptions=array(),$content=false,$closeTag=true)
- {
- $html='<' . $tag . self::renderAttributes($htmlOptions);
- if($content===false)
- return $closeTag && self::$closeSingleTags ? $html.' />' : $html.'>';
- else
- return $closeTag ? $html.'>'.$content.'</'.$tag.'>' : $html.'>'.$content;
- }
- public static function openTag($tag,$htmlOptions=array())
- {
- return '<' . $tag . self::renderAttributes($htmlOptions) . '>';
- }
- public static function closeTag($tag)
- {
- return '</'.$tag.'>';
- }
- public static function cdata($text)
- {
- return '<![CDATA[' . $text . ']]>';
- }
- public static function metaTag($content,$name=null,$httpEquiv=null,$options=array())
- {
- if($name!==null)
- $options['name']=$name;
- if($httpEquiv!==null)
- $options['http-equiv']=$httpEquiv;
- $options['content']=$content;
- return self::tag('meta',$options);
- }
- public static function linkTag($relation=null,$type=null,$href=null,$media=null,$options=array())
- {
- if($relation!==null)
- $options['rel']=$relation;
- if($type!==null)
- $options['type']=$type;
- if($href!==null)
- $options['href']=$href;
- if($media!==null)
- $options['media']=$media;
- return self::tag('link',$options);
- }
- public static function css($text,$media='')
- {
- if($media!=='')
- $media=' media="'.$media.'"';
- return "<style type=\"text/css\"{$media}>\n/*<![CDATA[*/\n{$text}\n/*]]>*/\n</style>";
- }
- public static function refresh($seconds,$url='')
- {
- $content="$seconds";
- if($url!=='')
- $content.=';url='.self::normalizeUrl($url);
- Yii::app()->clientScript->registerMetaTag($content,null,'refresh');
- }
- public static function cssFile($url,$media='')
- {
- return CHtml::linkTag('stylesheet','text/css',$url,$media!=='' ? $media : null);
- }
- public static function script($text,array $htmlOptions=array())
- {
- $defaultHtmlOptions=array(
- 'type'=>'text/javascript',
- );
- $htmlOptions=array_merge($defaultHtmlOptions,$htmlOptions);
- return self::tag('script',$htmlOptions,"\n/*<![CDATA[*/\n{$text}\n/*]]>*/\n");
- }
- public static function scriptFile($url,array $htmlOptions=array())
- {
- $defaultHtmlOptions=array(
- 'type'=>'text/javascript',
- 'src'=>$url
- );
- $htmlOptions=array_merge($defaultHtmlOptions,$htmlOptions);
- return self::tag('script',$htmlOptions,'');
- }
- public static function form($action='',$method='post',$htmlOptions=array())
- {
- return self::beginForm($action,$method,$htmlOptions);
- }
- public static function beginForm($action='',$method='post',$htmlOptions=array())
- {
- $htmlOptions['action']=$url=self::normalizeUrl($action);
- if(strcasecmp($method,'get')!==0 && strcasecmp($method,'post')!==0)
- {
- $customMethod=$method;
- $method='post';
- }
- else
- $customMethod=false;
- $htmlOptions['method']=$method;
- $form=self::tag('form',$htmlOptions,false,false);
- $hiddens=array();
- if(!strcasecmp($method,'get') && ($pos=strpos($url,'?'))!==false)
- {
- foreach(explode('&',substr($url,$pos+1)) as $pair)
- {
- if(($pos=strpos($pair,'='))!==false)
- $hiddens[]=self::hiddenField(urldecode(substr($pair,0,$pos)),urldecode(substr($pair,$pos+1)),array('id'=>false));
- else
- $hiddens[]=self::hiddenField(urldecode($pair),'',array('id'=>false));
- }
- }
- $request=Yii::app()->request;
- if($request->enableCsrfValidation && !strcasecmp($method,'post'))
- $hiddens[]=self::hiddenField($request->csrfTokenName,$request->getCsrfToken(),array('id'=>false));
- if($customMethod!==false)
- $hiddens[]=self::hiddenField('_method',$customMethod);
- if($hiddens!==array())
- $form.="\n".implode("\n",$hiddens);
- return $form;
- }
- public static function endForm()
- {
- return '</form>';
- }
- public static function statefulForm($action='',$method='post',$htmlOptions=array())
- {
- return self::form($action,$method,$htmlOptions)."\n".
- self::tag('div',array('style'=>'display:none'),self::pageStateField(''));
- }
- public static function pageStateField($value)
- {
- return '<input type="hidden" name="'.CController::STATE_INPUT_NAME.'" value="'.$value.'" />';
- }
- public static function link($text,$url='#',$htmlOptions=array())
- {
- if($url!=='')
- $htmlOptions['href']=self::normalizeUrl($url);
- self::clientChange('click',$htmlOptions);
- return self::tag('a',$htmlOptions,$text);
- }
- public static function mailto($text,$email='',$htmlOptions=array())
- {
- if($email==='')
- $email=$text;
- return self::link($text,'mailto:'.$email,$htmlOptions);
- }
- public static function image($src,$alt='',$htmlOptions=array())
- {
- $htmlOptions['src']=$src;
- $htmlOptions['alt']=$alt;
- return self::tag('img',$htmlOptions);
- }
- public static function button($label='button',$htmlOptions=array())
- {
- if(!isset($htmlOptions['name']))
- {
- if(!array_key_exists('name',$htmlOptions))
- $htmlOptions['name']=self::ID_PREFIX.self::$count++;
- }
- if(!isset($htmlOptions['type']))
- $htmlOptions['type']='button';
- if(!isset($htmlOptions['value']) && $htmlOptions['type']!='image')
- $htmlOptions['value']=$label;
- self::clientChange('click',$htmlOptions);
- return self::tag('input',$htmlOptions);
- }
- public static function htmlButton($label='button',$htmlOptions=array())
- {
- if(!isset($htmlOptions['name']))
- $htmlOptions['name']=self::ID_PREFIX.self::$count++;
- if(!isset($htmlOptions['type']))
- $htmlOptions['type']='button';
- self::clientChange('click',$htmlOptions);
- return self::tag('button',$htmlOptions,$label);
- }
- public static function submitButton($label='submit',$htmlOptions=array())
- {
- $htmlOptions['type']='submit';
- return self::button($label,$htmlOptions);
- }
- public static function resetButton($label='reset',$htmlOptions=array())
- {
- $htmlOptions['type']='reset';
- return self::button($label,$htmlOptions);
- }
- public static function imageButton($src,$htmlOptions=array())
- {
- $htmlOptions['src']=$src;
- $htmlOptions['type']='image';
- return self::button('submit',$htmlOptions);
- }
- public static function linkButton($label='submit',$htmlOptions=array())
- {
- if(!isset($htmlOptions['submit']))
- $htmlOptions['submit']=isset($htmlOptions['href']) ? $htmlOptions['href'] : '';
- return self::link($label,'#',$htmlOptions);
- }
- public static function label($label,$for,$htmlOptions=array())
- {
- if($for===false)
- unset($htmlOptions['for']);
- else
- $htmlOptions['for']=$for;
- if(isset($htmlOptions['required']))
- {
- if($htmlOptions['required'])
- {
- if(isset($htmlOptions['class']))
- $htmlOptions['class'].=' '.self::$requiredCss;
- else
- $htmlOptions['class']=self::$requiredCss;
- $label=self::$beforeRequiredLabel.$label.self::$afterRequiredLabel;
- }
- unset($htmlOptions['required']);
- }
- return self::tag('label',$htmlOptions,$label);
- }
- public static function colorField($name,$value='',$htmlOptions=array())
- {
- self::clientChange('change',$htmlOptions);
- return self::inputField('color',$name,$value,$htmlOptions);
- }
- public static function textField($name,$value='',$htmlOptions=array())
- {
- self::clientChange('change',$htmlOptions);
- return self::inputField('text',$name,$value,$htmlOptions);
- }
- public static function searchField($name,$value='',$htmlOptions=array())
- {
- self::clientChange('change',$htmlOptions);
- return self::inputField('search',$name,$value,$htmlOptions);
- }
- public static function numberField($name,$value='',$htmlOptions=array())
- {
- self::clientChange('change',$htmlOptions);
- return self::inputField('number',$name,$value,$htmlOptions);
- }
- public static function rangeField($name,$value='',$htmlOptions=array())
- {
- self::clientChange('change',$htmlOptions);
- return self::inputField('range',$name,$value,$htmlOptions);
- }
- public static function dateField($name,$value='',$htmlOptions=array())
- {
- self::clientChange('change',$htmlOptions);
- return self::inputField('date',$name,$value,$htmlOptions);
- }
- public static function timeField($name,$value='',$htmlOptions=array())
- {
- self::clientChange('change',$htmlOptions);
- return self::inputField('time',$name,$value,$htmlOptions);
- }
- public static function dateTimeField($name,$value='',$htmlOptions=array())
- {
- self::clientChange('change',$htmlOptions);
- return self::inputField('datetime',$name,$value,$htmlOptions);
- }
- public static function dateTimeLocalField($name,$value='',$htmlOptions=array())
- {
- self::clientChange('change',$htmlOptions);
- return self::inputField('datetime-local',$name,$value,$htmlOptions);
- }
- public static function weekField($name,$value='',$htmlOptions=array())
- {
- self::clientChange('change',$htmlOptions);
- return self::inputField('week',$name,$value,$htmlOptions);
- }
- public static function emailField($name,$value='',$htmlOptions=array())
- {
- self::clientChange('change',$htmlOptions);
- return self::inputField('email',$name,$value,$htmlOptions);
- }
- public static function telField($name,$value='',$htmlOptions=array())
- {
- self::clientChange('change',$htmlOptions);
- return self::inputField('tel',$name,$value,$htmlOptions);
- }
- public static function urlField($name,$value='',$htmlOptions=array())
- {
- self::clientChange('change',$htmlOptions);
- return self::inputField('url',$name,$value,$htmlOptions);
- }
- public static function hiddenField($name,$value='',$htmlOptions=array())
- {
- return self::inputField('hidden',$name,$value,$htmlOptions);
- }
- public static function passwordField($name,$value='',$htmlOptions=array())
- {
- self::clientChange('change',$htmlOptions);
- return self::inputField('password',$name,$value,$htmlOptions);
- }
- public static function fileField($name,$value='',$htmlOptions=array())
- {
- return self::inputField('file',$name,$value,$htmlOptions);
- }
- public static function textArea($name,$value='',$htmlOptions=array())
- {
- $htmlOptions['name']=$name;
- if(!isset($htmlOptions['id']))
- $htmlOptions['id']=self::getIdByName($name);
- elseif($htmlOptions['id']===false)
- unset($htmlOptions['id']);
- self::clientChange('change',$htmlOptions);
- return self::tag('textarea',$htmlOptions,isset($htmlOptions['encode']) && !$htmlOptions['encode'] ? $value : self::encode($value));
- }
- public static function radioButton($name,$checked=false,$htmlOptions=array())
- {
- if($checked)
- $htmlOptions['checked']='checked';
- else
- unset($htmlOptions['checked']);
- $value=isset($htmlOptions['value']) ? $htmlOptions['value'] : 1;
- self::clientChange('click',$htmlOptions);
- if(array_key_exists('uncheckValue',$htmlOptions))
- {
- $uncheck=$htmlOptions['uncheckValue'];
- unset($htmlOptions['uncheckValue']);
- }
- else
- $uncheck=null;
- if($uncheck!==null)
- {
- // add a hidden field so that if the radio button is not selected, it still submits a value
- if(isset($htmlOptions['id']) && $htmlOptions['id']!==false)
- $uncheckOptions=array('id'=>self::ID_PREFIX.$htmlOptions['id']);
- else
- $uncheckOptions=array('id'=>false);
- $hidden=self::hiddenField($name,$uncheck,$uncheckOptions);
- }
- else
- $hidden='';
- // add a hidden field so that if the radio button is not selected, it still submits a value
- return $hidden . self::inputField('radio',$name,$value,$htmlOptions);
- }
- public static function checkBox($name,$checked=false,$htmlOptions=array())
- {
- if($checked)
- $htmlOptions['checked']='checked';
- else
- unset($htmlOptions['checked']);
- $value=isset($htmlOptions['value']) ? $htmlOptions['value'] : 1;
- self::clientChange('click',$htmlOptions);
- if(array_key_exists('uncheckValue',$htmlOptions))
- {
- $uncheck=$htmlOptions['uncheckValue'];
- unset($htmlOptions['uncheckValue']);
- }
- else
- $uncheck=null;
- if($uncheck!==null)
- {
- // add a hidden field so that if the check box is not checked, it still submits a value
- if(isset($htmlOptions['id']) && $htmlOptions['id']!==false)
- $uncheckOptions=array('id'=>self::ID_PREFIX.$htmlOptions['id']);
- else
- $uncheckOptions=array('id'=>false);
- $hidden=self::hiddenField($name,$uncheck,$uncheckOptions);
- }
- else
- $hidden='';
- // add a hidden field so that if the check box is not checked, it still submits a value
- return $hidden . self::inputField('checkbox',$name,$value,$htmlOptions);
- }
- public static function dropDownList($name,$select,$data,$htmlOptions=array())
- {
- $htmlOptions['name']=$name;
- if(!isset($htmlOptions['id']))
- $htmlOptions['id']=self::getIdByName($name);
- elseif($htmlOptions['id']===false)
- unset($htmlOptions['id']);
- self::clientChange('change',$htmlOptions);
- $options="\n".self::listOptions($select,$data,$htmlOptions);
- $hidden='';
- if(!empty($htmlOptions['multiple']))
- {
- if(substr($htmlOptions['name'],-2)!=='[]')
- $htmlOptions['name'].='[]';
- if(isset($htmlOptions['unselectValue']))
- {
- $hiddenOptions=isset($htmlOptions['id']) ? array('id'=>self::ID_PREFIX.$htmlOptions['id']) : array('id'=>false);
- $hidden=self::hiddenField(substr($htmlOptions['name'],0,-2),$htmlOptions['unselectValue'],$hiddenOptions);
- unset($htmlOptions['unselectValue']);
- }
- }
- // add a hidden field so that if the option is not selected, it still submits a value
- return $hidden . self::tag('select',$htmlOptions,$options);
- }
- public static function listBox($name,$select,$data,$htmlOptions=array())
- {
- if(!isset($htmlOptions['size']))
- $htmlOptions['size']=4;
- if(!empty($htmlOptions['multiple']))
- {
- if(substr($name,-2)!=='[]')
- $name.='[]';
- }
- return self::dropDownList($name,$select,$data,$htmlOptions);
- }
- public static function checkBoxList($name,$select,$data,$htmlOptions=array())
- {
- $template=isset($htmlOptions['template'])?$htmlOptions['template']:'{input} {label}';
- $separator=isset($htmlOptions['separator'])?$htmlOptions['separator']:self::tag('br');
- $container=isset($htmlOptions['container'])?$htmlOptions['container']:'span';
- unset($htmlOptions['template'],$htmlOptions['separator'],$htmlOptions['container']);
- if(substr($name,-2)!=='[]')
- $name.='[]';
- if(isset($htmlOptions['checkAll']))
- {
- $checkAllLabel=$htmlOptions['checkAll'];
- $checkAllLast=isset($htmlOptions['checkAllLast']) && $htmlOptions['checkAllLast'];
- }
- unset($htmlOptions['checkAll'],$htmlOptions['checkAllLast']);
- $labelOptions=isset($htmlOptions['labelOptions'])?$htmlOptions['labelOptions']:array();
- unset($htmlOptions['labelOptions']);
- $items=array();
- $baseID=isset($htmlOptions['baseID']) ? $htmlOptions['baseID'] : self::getIdByName($name);
- unset($htmlOptions['baseID']);
- $id=0;
- $checkAll=true;
- foreach($data as $value=>$labelTitle)
- {
- $checked=!is_array($select) && !strcmp($value,$select) || is_array($select) && in_array($value,$select);
- $checkAll=$checkAll && $checked;
- $htmlOptions['value']=$value;
- $htmlOptions['id']=$baseID.'_'.$id++;
- $option=self::checkBox($name,$checked,$htmlOptions);
- $beginLabel=self::openTag('label',$labelOptions);
- $label=self::label($labelTitle,$htmlOptions['id'],$labelOptions);
- $endLabel=self::closeTag('label');
- $items[]=strtr($template,array(
- '{input}'=>$option,
- '{beginLabel}'=>$beginLabel,
- '{label}'=>$label,
- '{labelTitle}'=>$labelTitle,
- '{endLabel}'=>$endLabel,
- ));
- }
- if(isset($checkAllLabel))
- {
- $htmlOptions['value']=1;
- $htmlOptions['id']=$id=$baseID.'_all';
- $option=self::checkBox($id,$checkAll,$htmlOptions);
- $beginLabel=self::openTag('label',$labelOptions);
- $label=self::label($checkAllLabel,$id,$labelOptions);
- $endLabel=self::closeTag('label');
- $item=strtr($template,array(
- '{input}'=>$option,
- '{beginLabel}'=>$beginLabel,
- '{label}'=>$label,
- '{labelTitle}'=>$checkAllLabel,
- '{endLabel}'=>$endLabel,
- ));
- if($checkAllLast)
- $items[]=$item;
- else
- array_unshift($items,$item);
- $name=strtr($name,array('['=>'\\[',']'=>'\\]'));
- $js=<<<EOD
- jQuery('#$id').click(function() {
- jQuery("input[name='$name']").prop('checked', this.checked);
- });
- jQuery("input[name='$name']").click(function() {
- jQuery('#$id').prop('checked', !jQuery("input[name='$name']:not(:checked)").length);
- });
- jQuery('#$id').prop('checked', !jQuery("input[name='$name']:not(:checked)").length);
- EOD;
- $cs=Yii::app()->getClientScript();
- $cs->registerCoreScript('jquery');
- $cs->registerScript($id,$js);
- }
- if(empty($container))
- return implode($separator,$items);
- else
- return self::tag($container,array('id'=>$baseID),implode($separator,$items));
- }
- public static function radioButtonList($name,$select,$data,$htmlOptions=array())
- {
- $template=isset($htmlOptions['template'])?$htmlOptions['template']:'{input} {label}';
- $separator=isset($htmlOptions['separator'])?$htmlOptions['separator']:self::tag('br');
- $container=isset($htmlOptions['container'])?$htmlOptions['container']:'span';
- unset($htmlOptions['template'],$htmlOptions['separator'],$htmlOptions['container']);
- $labelOptions=isset($htmlOptions['labelOptions'])?$htmlOptions['labelOptions']:array();
- unset($htmlOptions['labelOptions']);
- if(isset($htmlOptions['empty']))
- {
- if(!is_array($htmlOptions['empty']))
- $htmlOptions['empty']=array(''=>$htmlOptions['empty']);
- $data=CMap::mergeArray($htmlOptions['empty'],$data);
- unset($htmlOptions['empty']);
- }
- $items=array();
- $baseID=isset($htmlOptions['baseID']) ? $htmlOptions['baseID'] : self::getIdByName($name);
- unset($htmlOptions['baseID']);
- $id=0;
- foreach($data as $value=>$labelTitle)
- {
- $checked=!strcmp($value,$select);
- $htmlOptions['value']=$value;
- $htmlOptions['id']=$baseID.'_'.$id++;
- $option=self::radioButton($name,$checked,$htmlOptions);
- $beginLabel=self::openTag('label',$labelOptions);
- $label=self::label($labelTitle,$htmlOptions['id'],$labelOptions);
- $endLabel=self::closeTag('label');
- $items[]=strtr($template,array(
- '{input}'=>$option,
- '{beginLabel}'=>$beginLabel,
- '{label}'=>$label,
- '{labelTitle}'=>$labelTitle,
- '{endLabel}'=>$endLabel,
- ));
- }
- if(empty($container))
- return implode($separator,$items);
- else
- return self::tag($container,array('id'=>$baseID),implode($separator,$items));
- }
- public static function ajaxLink($text,$url,$ajaxOptions=array(),$htmlOptions=array())
- {
- if(!isset($htmlOptions['href']))
- $htmlOptions['href']='#';
- $ajaxOptions['url']=$url;
- $htmlOptions['ajax']=$ajaxOptions;
- self::clientChange('click',$htmlOptions);
- return self::tag('a',$htmlOptions,$text);
- }
- public static function ajaxButton($label,$url,$ajaxOptions=array(),$htmlOptions=array())
- {
- $ajaxOptions['url']=$url;
- $htmlOptions['ajax']=$ajaxOptions;
- return self::button($label,$htmlOptions);
- }
- public static function ajaxSubmitButton($label,$url,$ajaxOptions=array(),$htmlOptions=array())
- {
- $ajaxOptions['type']='POST';
- $htmlOptions['type']='submit';
- return self::ajaxButton($label,$url,$ajaxOptions,$htmlOptions);
- }
- public static function ajax($options)
- {
- Yii::app()->getClientScript()->registerCoreScript('jquery');
- if(!isset($options['url']))
- $options['url']=new CJavaScriptExpression('location.href');
- else
- $options['url']=self::normalizeUrl($options['url']);
- if(!isset($options['cache']))
- $options['cache']=false;
- if(!isset($options['data']) && isset($options['type']))
- $options['data']=new CJavaScriptExpression('jQuery(this).parents("form").serialize()');
- foreach(array('beforeSend','complete','error','success') as $name)
- {
- if(isset($options[$name]) && !($options[$name] instanceof CJavaScriptExpression))
- $options[$name]=new CJavaScriptExpression($options[$name]);
- }
- if(isset($options['update']))
- {
- if(!isset($options['success']))
- $options['success']=new CJavaScriptExpression('function(html){jQuery("'.$options['update'].'").html(html)}');
- unset($options['update']);
- }
- if(isset($options['replace']))
- {
- if(!isset($options['success']))
- $options['success']=new CJavaScriptExpression('function(html){jQuery("'.$options['replace'].'").replaceWith(html)}');
- unset($options['replace']);
- }
- return 'jQuery.ajax('.CJavaScript::encode($options).');';
- }
- public static function asset($path,$hashByName=false)
- {
- return Yii::app()->getAssetManager()->publish($path,$hashByName);
- }
- public static function normalizeUrl($url)
- {
- if(is_array($url))
- {
- if(isset($url[0]))
- {
- if(($c=Yii::app()->getController())!==null)
- $url=$c->createUrl($url[0],array_splice($url,1));
- else
- $url=Yii::app()->createUrl($url[0],array_splice($url,1));
- }
- else
- $url='';
- }
- return $url==='' ? Yii::app()->getRequest()->getUrl() : $url;
- }
- protected static function inputField($type,$name,$value,$htmlOptions)
- {
- $htmlOptions['type']=$type;
- $htmlOptions['value']=$value;
- $htmlOptions['name']=$name;
- if(!isset($htmlOptions['id']))
- $htmlOptions['id']=self::getIdByName($name);
- elseif($htmlOptions['id']===false)
- unset($htmlOptions['id']);
- return self::tag('input',$htmlOptions);
- }
- public static function activeLabel($model,$attribute,$htmlOptions=array())
- {
- $inputName=self::resolveName($model,$attribute);
- if(isset($htmlOptions['for']))
- {
- $for=$htmlOptions['for'];
- unset($htmlOptions['for']);
- }
- else
- $for=self::getIdByName($inputName);
- if(isset($htmlOptions['label']))
- {
- if(($label=$htmlOptions['label'])===false)
- return '';
- unset($htmlOptions['label']);
- }
- else
- $label=$model->getAttributeLabel($attribute);
- if($model->hasErrors($attribute))
- self::addErrorCss($htmlOptions);
- return self::label($label,$for,$htmlOptions);
- }
- public static function activeLabelEx($model,$attribute,$htmlOptions=array())
- {
- $realAttribute=$attribute;
- self::resolveName($model,$attribute); // strip off square brackets if any
- $htmlOptions['required']=$model->isAttributeRequired($attribute);
- return self::activeLabel($model,$realAttribute,$htmlOptions);
- }
- public static function activeTextField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- return self::activeInputField('text',$model,$attribute,$htmlOptions);
- }
- public static function activeSearchField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- return self::activeInputField('search',$model,$attribute,$htmlOptions);
- }
- public static function activeUrlField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- return self::activeInputField('url',$model,$attribute,$htmlOptions);
- }
- public static function activeEmailField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- return self::activeInputField('email',$model,$attribute,$htmlOptions);
- }
- public static function activeNumberField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- return self::activeInputField('number',$model,$attribute,$htmlOptions);
- }
- public static function activeRangeField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- return self::activeInputField('range',$model,$attribute,$htmlOptions);
- }
- public static function activeDateField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- return self::activeInputField('date',$model,$attribute,$htmlOptions);
- }
- public static function activeTimeField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- return self::activeInputField('time',$model,$attribute,$htmlOptions);
- }
- public static function activeDateTimeField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- return self::activeInputField('datetime',$model,$attribute,$htmlOptions);
- }
- public static function activeDateTimeLocalField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- return self::activeInputField('datetime-local',$model,$attribute,$htmlOptions);
- }
- public static function activeWeekField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- return self::activeInputField('week',$model,$attribute,$htmlOptions);
- }
- public static function activeColorField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- return self::activeInputField('color',$model,$attribute,$htmlOptions);
- }
- public static function activeTelField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- return self::activeInputField('tel',$model,$attribute,$htmlOptions);
- }
- public static function activeHiddenField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- return self::activeInputField('hidden',$model,$attribute,$htmlOptions);
- }
- public static function activePasswordField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- return self::activeInputField('password',$model,$attribute,$htmlOptions);
- }
- public static function activeTextArea($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- if($model->hasErrors($attribute))
- self::addErrorCss($htmlOptions);
- if(isset($htmlOptions['value']))
- {
- $text=$htmlOptions['value'];
- unset($htmlOptions['value']);
- }
- else
- $text=self::resolveValue($model,$attribute);
- return self::tag('textarea',$htmlOptions,isset($htmlOptions['encode']) && !$htmlOptions['encode'] ? $text : self::encode($text));
- }
- public static function activeFileField($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- // add a hidden field so that if a model only has a file field, we can
- // still use isset($_POST[$modelClass]) to detect if the input is submitted
- $hiddenOptions=isset($htmlOptions['id']) ? array('id'=>self::ID_PREFIX.$htmlOptions['id']) : array('id'=>false);
- return self::hiddenField($htmlOptions['name'],'',$hiddenOptions)
- . self::activeInputField('file',$model,$attribute,$htmlOptions);
- }
- public static function activeRadioButton($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- if(!isset($htmlOptions['value']))
- $htmlOptions['value']=1;
- if(!isset($htmlOptions['checked']) && self::resolveValue($model,$attribute)==$htmlOptions['value'])
- $htmlOptions['checked']='checked';
- self::clientChange('click',$htmlOptions);
- if(array_key_exists('uncheckValue',$htmlOptions))
- {
- $uncheck=$htmlOptions['uncheckValue'];
- unset($htmlOptions['uncheckValue']);
- }
- else
- $uncheck='0';
- $hiddenOptions=isset($htmlOptions['id']) ? array('id'=>self::ID_PREFIX.$htmlOptions['id']) : array('id'=>false);
- $hidden=$uncheck!==null ? self::hiddenField($htmlOptions['name'],$uncheck,$hiddenOptions) : '';
- // add a hidden field so that if the radio button is not selected, it still submits a value
- return $hidden . self::activeInputField('radio',$model,$attribute,$htmlOptions);
- }
- public static function activeCheckBox($model,$attribute,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- if(!isset($htmlOptions['value']))
- $htmlOptions['value']=1;
- if(!isset($htmlOptions['checked']) && self::resolveValue($model,$attribute)==$htmlOptions['value'])
- $htmlOptions['checked']='checked';
- self::clientChange('click',$htmlOptions);
- if(array_key_exists('uncheckValue',$htmlOptions))
- {
- $uncheck=$htmlOptions['uncheckValue'];
- unset($htmlOptions['uncheckValue']);
- }
- else
- $uncheck='0';
- $hiddenOptions=isset($htmlOptions['id']) ? array('id'=>self::ID_PREFIX.$htmlOptions['id']) : array('id'=>false);
- $hidden=$uncheck!==null ? self::hiddenField($htmlOptions['name'],$uncheck,$hiddenOptions) : '';
- return $hidden . self::activeInputField('checkbox',$model,$attribute,$htmlOptions);
- }
- public static function activeDropDownList($model,$attribute,$data,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- $selection=self::resolveValue($model,$attribute);
- $options="\n".self::listOptions($selection,$data,$htmlOptions);
- self::clientChange('change',$htmlOptions);
- if($model->hasErrors($attribute))
- self::addErrorCss($htmlOptions);
- $hidden='';
- if(!empty($htmlOptions['multiple']))
- {
- if(substr($htmlOptions['name'],-2)!=='[]')
- $htmlOptions['name'].='[]';
- if(isset($htmlOptions['unselectValue']))
- {
- $hiddenOptions=isset($htmlOptions['id']) ? array('id'=>self::ID_PREFIX.$htmlOptions['id']) : array('id'=>false);
- $hidden=self::hiddenField(substr($htmlOptions['name'],0,-2),$htmlOptions['unselectValue'],$hiddenOptions);
- unset($htmlOptions['unselectValue']);
- }
- }
- return $hidden . self::tag('select',$htmlOptions,$options);
- }
- public static function activeListBox($model,$attribute,$data,$htmlOptions=array())
- {
- if(!isset($htmlOptions['size']))
- $htmlOptions['size']=4;
- return self::activeDropDownList($model,$attribute,$data,$htmlOptions);
- }
- public static function activeCheckBoxList($model,$attribute,$data,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- $selection=self::resolveValue($model,$attribute);
- if($model->hasErrors($attribute))
- self::addErrorCss($htmlOptions);
- $name=$htmlOptions['name'];
- unset($htmlOptions['name']);
- if(array_key_exists('uncheckValue',$htmlOptions))
- {
- $uncheck=$htmlOptions['uncheckValue'];
- unset($htmlOptions['uncheckValue']);
- }
- else
- $uncheck='';
- $hiddenOptions=isset($htmlOptions['id']) ? array('id'=>self::ID_PREFIX.$htmlOptions['id']) : array('id'=>false);
- $hidden=$uncheck!==null ? self::hiddenField($name,$uncheck,$hiddenOptions) : '';
- return $hidden . self::checkBoxList($name,$selection,$data,$htmlOptions);
- }
- public static function activeRadioButtonList($model,$attribute,$data,$htmlOptions=array())
- {
- self::resolveNameID($model,$attribute,$htmlOptions);
- $selection=self::resolveValue($model,$attribute);
- if($model->hasErrors($attribute))
- self::addErrorCss($htmlOptions);
- $name=$htmlOptions['name'];
- unset($htmlOptions['name']);
- if(array_key_exists('uncheckValue',$htmlOptions))
- {
- $uncheck=$htmlOptions['uncheckValue'];
- unset($htmlOptions['uncheckValue']);
- }
- else
- $uncheck='';
- $hiddenOptions=isset($htmlOptions['id']) ? array('id'=>self::ID_PREFIX.$htmlOptions['id']) : array('id'=>false);
- $hidden=$uncheck!==null ? self::hiddenField($name,$uncheck,$hiddenOptions) : '';
- return $hidden . self::radioButtonList($name,$selection,$data,$htmlOptions);
- }
- public static function errorSummary($model,$header=null,$footer=null,$htmlOptions=array())
- {
- $content='';
- if(!is_array($model))
- $model=array($model);
- if(isset($htmlOptions['firstError']))
- {
- $firstError=$htmlOptions['firstError'];
- unset($htmlOptions['firstError']);
- }
- else
- $firstError=false;
- foreach($model as $m)
- {
- foreach($m->getErrors() as $errors)
- {
- foreach($errors as $error)
- {
- if($error!='')
- $content.="<li>$error</li>\n";
- if($firstError)
- break;
- }
- }
- }
- if($content!=='')
- {
- if($header===null)
- $header='<p>'.Yii::t('yii','Please fix the following input errors:').'</p>';
- if(!isset($htmlOptions['class']))
- $htmlOptions['class']=self::$errorSummaryCss;
- return self::tag('div',$htmlOptions,$header."\n<ul>\n$content</ul>".$footer);
- }
- else
- return '';
- }
- public static function error($model,$attribute,$htmlOptions=array())
- {
- self::resolveName($model,$attribute); // turn [a][b]attr into attr
- $error=$model->getError($attribute);
- if($error!='')
- {
- if(!isset($htmlOptions['class']))
- $htmlOptions['class']=self::$errorMessageCss;
- return self::tag(self::$errorContainerTag,$htmlOptions,$error);
- }
- else
- return '';
- }
- public static function listData($models,$valueField,$textField,$groupField='')
- {
- $listData=array();
- if($groupField==='')
- {
- foreach($models as $model)
- {
- $value=self::value($model,$valueField);
- $text=self::value($model,$textField);
- $listData[$value]=$text;
- }
- }
- else
- {
- foreach($models as $model)
- {
- $group=self::value($model,$groupField);
- $value=self::value($model,$valueField);
- $text=self::value($model,$textField);
- if($group===null)
- $listData[$value]=$text;
- else
- $listData[$group][$value]=$text;
- }
- }
- return $listData;
- }
- public static function value($model,$attribute,$defaultValue=null)
- {
- if(is_scalar($attribute) || $attribute===null)
- foreach(explode('.',$attribute) as $name)
- {
- if(is_object($model) && isset($model->$name))
- $model=$model->$name;
- elseif(is_array($model) && isset($model[$name]))
- $model=$model[$name];
- else
- return $defaultValue;
- }
- else
- return call_user_func($attribute,$model);
- return $model;
- }
- public static function getIdByName($name)
- {
- return str_replace(array('[]','][','[',']',' '),array('','_','_','','_'),$name);
- }
- public static function activeId($model,$attribute)
- {
- return self::getIdByName(self::activeName($model,$attribute));
- }
- public static function modelName($model)
- {
- if(is_callable(self::$_modelNameConverter))
- return call_user_func(self::$_modelNameConverter,$model);
- $className=is_object($model) ? get_class($model) : (string)$model;
- return trim(str_replace('\\','_',$className),'_');
- }
- public static function setModelNameConverter($converter)
- {
- if(is_callable($converter))
- self::$_modelNameConverter=$converter;
- elseif($converter===null)
- self::$_modelNameConverter=null;
- else
- throw new CException(Yii::t('yii','The $converter argument must be a valid callback or null.'));
- }
- public static function activeName($model,$attribute)
- {
- $a=$attribute; // because the attribute name may be changed by resolveName
- return self::resolveName($model,$a);
- }
- protected static function activeInputField($type,$model,$attribute,$htmlOptions)
- {
- $htmlOptions['type']=$type;
- if($type==='text'||$type==='password'||$type==='color'||$type==='date'||$type==='datetime'||
- $type==='datetime-local'||$type==='email'||$type==='month'||$type==='number'||$type==='range'||
- $type==='search'||$type==='tel'||$type==='time'||$type==='url'||$type==='week')
- {
- if(!isset($htmlOptions['maxlength']))
- {
- foreach($model->getValidators($attribute) as $validator)
- {
- if($validator instanceof CStringValidator && $validator->max!==null)
- {
- $htmlOptions['maxlength']=$validator->max;
- break;
- }
- }
- }
- elseif($htmlOptions['maxlength']===false)
- unset($htmlOptions['maxlength']);
- }
- if($type==='file')
- unset($htmlOptions['value']);
- elseif(!isset($htmlOptions['value']))
- $htmlOptions['value']=self::resolveValue($model,$attribute);
- if($model->hasErrors($attribute))
- self::addErrorCss($htmlOptions);
- return self::tag('input',$htmlOptions);
- }
- public static function listOptions($selection,$listData,&$htmlOptions)
- {
- $raw=isset($htmlOptions['encode']) && !$htmlOptions['encode'];
- $content='';
- if(isset($htmlOptions['prompt']))
- {
- $content.='<option value="">'.strtr($htmlOptions['prompt'],array('<'=>'<','>'=>'>'))."</option>\n";
- unset($htmlOptions['prompt']);
- }
- if(isset($htmlOptions['empty']))
- {
- if(!is_array($htmlOptions['empty']))
- $htmlOptions['empty']=array(''=>$htmlOptions['empty']);
- foreach($htmlOptions['empty'] as $value=>$label)
- $content.='<option value="'.self::encode($value).'">'.strtr($label,array('<'=>'<','>'=>'>'))."</option>\n";
- unset($htmlOptions['empty']);
- }
- if(isset($htmlOptions['options']))
- {
- $options=$htmlOptions['options'];
- unset($htmlOptions['options']);
- }
- else
- $options=array();
- $key=isset($htmlOptions['key']) ? $htmlOptions['key'] : 'primaryKey';
- if(is_array($selection))
- {
- foreach($selection as $i=>$item)
- {
- if(is_object($item))
- $selection[$i]=$item->$key;
- }
- }
- elseif(is_object($selection))
- $selection=$selection->$key;
- foreach($listData as $key=>$value)
- {
- if(is_array($value))
- {
- $content.='<optgroup label="'.($raw?$key : self::encode($key))."\">\n";
- $dummy=array('options'=>$options);
- if(isset($htmlOptions['encode']))
- $dummy['encode']=$htmlOptions['encode'];
- $content.=self::listOptions($selection,$value,$dummy);
- $content.='</optgroup>'."\n";
- }
- else
- {
- $attributes=array('value'=>(string)$key,'encode'=>!$raw);
- if(!is_array($selection) && !strcmp($key,$selection) || is_array($selection) && in_array($key,$selection))
- $attributes['selected']='selected';
- if(isset($options[$key]))
- $attributes=array_merge($attributes,$options[$key]);
- $content.=self::tag('option',$attributes,$raw?(string)$value : self::encode((string)$value))."\n";
- }
- }
- unset($htmlOptions['key']);
- return $content;
- }
- protected static function clientChange($event,&$htmlOptions)
- {
- if(!isset($htmlOptions['submit']) && !isset($htmlOptions['confirm']) && !isset($htmlOptions['ajax']))
- return;
- if(isset($htmlOptions['live']))
- {
- $live=$htmlOptions['live'];
- unset($htmlOptions['live']);
- }
- else
- $live = self::$liveEvents;
- if(isset($htmlOptions['return']) && $htmlOptions['return'])
- $return='return true';
- else
- $return='return false';
- if(isset($htmlOptions['on'.$event]))
- {
- $handler=trim($htmlOptions['on'.$event],';').';';
- unset($htmlOptions['on'.$event]);
- }
- else
- $handler='';
- if(isset($htmlOptions['id']))
- $id=$htmlOptions['id'];
- else
- $id=$htmlOptions['id']=isset($htmlOptions['name'])?$htmlOptions['name']:self::ID_PREFIX.self::$count++;
- $cs=Yii::app()->getClientScript();
- $cs->registerCoreScript('jquery');
- if(isset($htmlOptions['submit']))
- {
- $cs->registerCoreScript('yii');
- $request=Yii::app()->getRequest();
- if($request->enableCsrfValidation && isset($htmlOptions['csrf']) && $htmlOptions['csrf'])
- $htmlOptions['params'][$request->csrfTokenName]=$request->getCsrfToken();
- if(isset($htmlOptions['params']))
- $params=CJavaScript::encode($htmlOptions['params']);
- else
- $params='{}';
- if($htmlOptions['submit']!=='')
- $url=CJavaScript::quote(self::normalizeUrl($htmlOptions['submit']));
- else
- $url='';
- $handler.="jQuery.yii.submitForm(this,'$url',$params);{$return};";
- }
- if(isset($htmlOptions['ajax']))
- $handler.=self::ajax($htmlOptions['ajax'])."{$return};";
- if(isset($htmlOptions['confirm']))
- {
- $confirm='confirm(\''.CJavaScript::quote($htmlOptions['confirm']).'\')';
- if($handler!=='')
- $handler="if($confirm) {".$handler."} else return false;";
- else
- $handler="return $confirm;";
- }
- if($live)
- $cs->registerScript('Yii.CHtml.#' . $id,"jQuery('body').on('$event','#$id',function(){{$handler}});");
- else
- $cs->registerScript('Yii.CHtml.#' . $id,"jQuery('#$id').on('$event', function(){{$handler}});");
- unset($htmlOptions['params'],$htmlOptions['submit'],$htmlOptions['ajax'],$htmlOptions['confirm'],$htmlOptions['return'],$htmlOptions['csrf']);
- }
- public static function resolveNameID($model,&$attribute,&$htmlOptions)
- {
- if(!isset($htmlOptions['name']))
- $htmlOptions['name']=self::resolveName($model,$attribute);
- if(!isset($htmlOptions['id']))
- $htmlOptions['id']=self::getIdByName($htmlOptions['name']);
- elseif($htmlOptions['id']===false)
- unset($htmlOptions['id']);
- }
- public static function resolveName($model,&$attribute)
- {
- $modelName=self::modelName($model);
- if(($pos=strpos($attribute,'['))!==false)
- {
- if($pos!==0) // e.g. name[a][b]
- return $modelName.'['.substr($attribute,0,$pos).']'.substr($attribute,$pos);
- if(($pos=strrpos($attribute,']'))!==false && $pos!==strlen($attribute)-1) // e.g. [a][b]name
- {
- $sub=substr($attribute,0,$pos+1);
- $attribute=substr($attribute,$pos+1);
- return $modelName.$sub.'['.$attribute.']';
- }
- if(preg_match('/\](\w+\[.*)$/',$attribute,$matches))
- {
- $name=$modelName.'['.str_replace(']','][',trim(strtr($attribute,array(']['=>']','['=>']')),']')).']';
- $attribute=$matches[1];
- return $name;
- }
- }
- return $modelName.'['.$attribute.']';
- }
- public static function resolveValue($model,$attribute)
- {
- if(($pos=strpos($attribute,'['))!==false)
- {
- if($pos===0) // [a]name[b][c], should ignore [a]
- {
- if(preg_match('/\](\w+(\[.+)?)/',$attribute,$matches))
- $attribute=$matches[1]; // we get: name[b][c]
- if(($pos=strpos($attribute,'['))===false)
- return $model->$attribute;
- }
- $name=substr($attribute,0,$pos);
- $value=$model->$name;
- foreach(explode('][',rtrim(substr($attribute,$pos+1),']')) as $id)
- {
- if((is_array($value) || $value instanceof ArrayAccess) && isset($value[$id]))
- $value=$value[$id];
- else
- return null;
- }
- return $value;
- }
- else
- return $model->$attribute;
- }
- protected static function addErrorCss(&$htmlOptions)
- {
- if(empty(self::$errorCss))
- return;
- if(isset($htmlOptions['class']))
- $htmlOptions['class'].=' '.self::$errorCss;
- else
- $htmlOptions['class']=self::$errorCss;
- }
- public static function renderAttributes($htmlOptions)
- {
- static $specialAttributes=array(
- 'autofocus'=>1,
- 'autoplay'=>1,
- 'async'=>1,
- 'checked'=>1,
- 'controls'=>1,
- 'declare'=>1,
- 'default'=>1,
- 'defer'=>1,
- 'disabled'=>1,
- 'formnovalidate'=>1,
- 'hidden'=>1,
- 'ismap'=>1,
- 'itemscope'=>1,
- 'loop'=>1,
- 'multiple'=>1,
- 'muted'=>1,
- 'nohref'=>1,
- 'noresize'=>1,
- 'novalidate'=>1,
- 'open'=>1,
- 'readonly'=>1,
- 'required'=>1,
- 'reversed'=>1,
- 'scoped'=>1,
- 'seamless'=>1,
- 'selected'=>1,
- 'typemustmatch'=>1,
- );
- if($htmlOptions===array())
- return '';
- $html='';
- if(isset($htmlOptions['encode']))
- {
- $raw=!$htmlOptions['encode'];
- unset($htmlOptions['encode']);
- }
- else
- $raw=false;
- foreach($htmlOptions as $name=>$value)
- {
- if(isset($specialAttributes[$name]))
- {
- if($value===false && $name==='async') {
- $html .= ' ' . $name.'="false"';
- }
- elseif($value)
- {
- $html .= ' ' . $name;
- if(self::$renderSpecialAttributesValue)
- $html .= '="' . $name . '"';
- }
- }
- elseif($value!==null)
- $html .= ' ' . $name . '="' . ($raw ? $value : self::encode($value)) . '"';
- }
- return $html;
- }
- }
- class CWidgetFactory extends CApplicationComponent implements IWidgetFactory
- {
- public $enableSkin=false;
- public $widgets=array();
- public $skinnableWidgets;
- public $skinPath;
- private $_skins=array(); // class name, skin name, property name => value
- public function init()
- {
- parent::init();
- if($this->enableSkin && $this->skinPath===null)
- $this->skinPath=Yii::app()->getViewPath().DIRECTORY_SEPARATOR.'skins';
- }
- public function createWidget($owner,$className,$properties=array())
- {
- $className=Yii::import($className,true);
- $widget=new $className($owner);
- if(isset($this->widgets[$className]))
- $properties=$properties===array() ? $this->widgets[$className] : CMap::mergeArray($this->widgets[$className],$properties);
- if($this->enableSkin)
- {
- if($this->skinnableWidgets===null || in_array($className,$this->skinnableWidgets))
- {
- $skinName=isset($properties['skin']) ? $properties['skin'] : 'default';
- if($skinName!==false && ($skin=$this->getSkin($className,$skinName))!==array())
- $properties=$properties===array() ? $skin : CMap::mergeArray($skin,$properties);
- }
- }
- foreach($properties as $name=>$value)
- $widget->$name=$value;
- return $widget;
- }
- protected function getSkin($className,$skinName)
- {
- if(!isset($this->_skins[$className][$skinName]))
- {
- $skinFile=$this->skinPath.DIRECTORY_SEPARATOR.$className.'.php';
- if(is_file($skinFile))
- $this->_skins[$className]=require($skinFile);
- else
- $this->_skins[$className]=array();
- if(($theme=Yii::app()->getTheme())!==null)
- {
- $skinFile=$theme->getSkinPath().DIRECTORY_SEPARATOR.$className.'.php';
- if(is_file($skinFile))
- {
- $skins=require($skinFile);
- foreach($skins as $name=>$skin)
- $this->_skins[$className][$name]=$skin;
- }
- }
- if(!isset($this->_skins[$className][$skinName]))
- $this->_skins[$className][$skinName]=array();
- }
- return $this->_skins[$className][$skinName];
- }
- }
- class CWidget extends CBaseController
- {
- public $actionPrefix;
- public $skin='default';
- private static $_viewPaths;
- private static $_counter=0;
- private $_id;
- private $_owner;
- public static function actions()
- {
- return array();
- }
- public function __construct($owner=null)
- {
- $this->_owner=$owner===null?Yii::app()->getController():$owner;
- }
- public function getOwner()
- {
- return $this->_owner;
- }
- public function getId($autoGenerate=true)
- {
- if($this->_id!==null)
- return $this->_id;
- elseif($autoGenerate)
- return $this->_id='yw'.self::$_counter++;
- }
- public function setId($value)
- {
- $this->_id=$value;
- }
- public function getController()
- {
- if($this->_owner instanceof CController)
- return $this->_owner;
- else
- return Yii::app()->getController();
- }
- public function init()
- {
- }
- public function run()
- {
- }
- public function getViewPath($checkTheme=false)
- {
- $className=get_class($this);
- $scope=$checkTheme?'theme':'local';
- if(isset(self::$_viewPaths[$className][$scope]))
- return self::$_viewPaths[$className][$scope];
- else
- {
- if($checkTheme && ($theme=Yii::app()->getTheme())!==null)
- {
- $path=$theme->getViewPath().DIRECTORY_SEPARATOR;
- if(strpos($className,'\\')!==false) // namespaced class
- $path.=str_replace('\\','_',ltrim($className,'\\'));
- else
- $path.=$className;
- if(is_dir($path))
- return self::$_viewPaths[$className]['theme']=$path;
- }
- $class=new ReflectionClass($className);
- return self::$_viewPaths[$className]['local']=dirname($class->getFileName()).DIRECTORY_SEPARATOR.'views';
- }
- }
- public function getViewFile($viewName)
- {
- if(($renderer=Yii::app()->getViewRenderer())!==null)
- $extension=$renderer->fileExtension;
- else
- $extension='.php';
- if(strpos($viewName,'.')) // a path alias
- $viewFile=Yii::getPathOfAlias($viewName);
- else
- {
- $viewFile=$this->getViewPath(true).DIRECTORY_SEPARATOR.$viewName;
- if(is_file($viewFile.$extension))
- return Yii::app()->findLocalizedFile($viewFile.$extension);
- elseif($extension!=='.php' && is_file($viewFile.'.php'))
- return Yii::app()->findLocalizedFile($viewFile.'.php');
- $viewFile=$this->getViewPath(false).DIRECTORY_SEPARATOR.$viewName;
- }
- if(is_file($viewFile.$extension))
- return Yii::app()->findLocalizedFile($viewFile.$extension);
- elseif($extension!=='.php' && is_file($viewFile.'.php'))
- return Yii::app()->findLocalizedFile($viewFile.'.php');
- else
- return false;
- }
- public function render($view,$data=null,$return=false)
- {
- if(($viewFile=$this->getViewFile($view))!==false)
- return $this->renderFile($viewFile,$data,$return);
- else
- throw new CException(Yii::t('yii','{widget} cannot find the view "{view}".',
- array('{widget}'=>get_class($this), '{view}'=>$view)));
- }
- }
- class CClientScript extends CApplicationComponent
- {
- const POS_HEAD=0;
- const POS_BEGIN=1;
- const POS_END=2;
- const POS_LOAD=3;
- const POS_READY=4;
- public $enableJavaScript=true;
- public $scriptMap=array();
- public $packages=array();
- public $corePackages;
- public $scripts=array();
- protected $cssFiles=array();
- protected $scriptFiles=array();
- protected $metaTags=array();
- protected $linkTags=array();
- protected $css=array();
- protected $hasScripts=false;
- protected $coreScripts=array();
- public $coreScriptPosition=self::POS_HEAD;
- public $defaultScriptFilePosition=self::POS_HEAD;
- public $defaultScriptPosition=self::POS_READY;
- private $_baseUrl;
- public function reset()
- {
- $this->hasScripts=false;
- $this->coreScripts=array();
- $this->cssFiles=array();
- $this->css=array();
- $this->scriptFiles=array();
- $this->scripts=array();
- $this->metaTags=array();
- $this->linkTags=array();
- $this->recordCachingAction('clientScript','reset',array());
- }
- public function render(&$output)
- {
- if(!$this->hasScripts)
- return;
- $this->renderCoreScripts();
- if(!empty($this->scriptMap))
- $this->remapScripts();
- $this->unifyScripts();
- $this->renderHead($output);
- if($this->enableJavaScript)
- {
- $this->renderBodyBegin($output);
- $this->renderBodyEnd($output);
- }
- }
- protected function unifyScripts()
- {
- if(!$this->enableJavaScript)
- return;
- $map=array();
- if(isset($this->scriptFiles[self::POS_HEAD]))
- $map=$this->scriptFiles[self::POS_HEAD];
- if(isset($this->scriptFiles[self::POS_BEGIN]))
- {
- foreach($this->scriptFiles[self::POS_BEGIN] as $scriptFile=>$scriptFileValue)
- {
- if(isset($map[$scriptFile]))
- unset($this->scriptFiles[self::POS_BEGIN][$scriptFile]);
- else
- $map[$scriptFile]=true;
- }
- }
- if(isset($this->scriptFiles[self::POS_END]))
- {
- foreach($this->scriptFiles[self::POS_END] as $key=>$scriptFile)
- {
- if(isset($map[$key]))
- unset($this->scriptFiles[self::POS_END][$key]);
- }
- }
- }
- protected function remapScripts()
- {
- $cssFiles=array();
- foreach($this->cssFiles as $url=>$media)
- {
- $name=basename($url);
- if(isset($this->scriptMap[$name]))
- {
- if($this->scriptMap[$name]!==false)
- $cssFiles[$this->scriptMap[$name]]=$media;
- }
- elseif(isset($this->scriptMap['*.css']))
- {
- if($this->scriptMap['*.css']!==false)
- $cssFiles[$this->scriptMap['*.css']]=$media;
- }
- else
- $cssFiles[$url]=$media;
- }
- $this->cssFiles=$cssFiles;
- $jsFiles=array();
- foreach($this->scriptFiles as $position=>$scriptFiles)
- {
- $jsFiles[$position]=array();
- foreach($scriptFiles as $scriptFile=>$scriptFileValue)
- {
- $name=basename($scriptFile);
- if(isset($this->scriptMap[$name]))
- {
- if($this->scriptMap[$name]!==false)
- $jsFiles[$position][$this->scriptMap[$name]]=$this->scriptMap[$name];
- }
- elseif(isset($this->scriptMap['*.js']))
- {
- if($this->scriptMap['*.js']!==false)
- $jsFiles[$position][$this->scriptMap['*.js']]=$this->scriptMap['*.js'];
- }
- else
- $jsFiles[$position][$scriptFile]=$scriptFileValue;
- }
- }
- $this->scriptFiles=$jsFiles;
- }
- protected function renderScriptBatch(array $scripts)
- {
- $html = '';
- $scriptBatches = array();
- foreach($scripts as $scriptValue)
- {
- if(is_array($scriptValue))
- {
- $scriptContent = $scriptValue['content'];
- unset($scriptValue['content']);
- $scriptHtmlOptions = $scriptValue;
- ksort($scriptHtmlOptions);
- }
- else
- {
- $scriptContent = $scriptValue;
- $scriptHtmlOptions = array();
- }
- $key=serialize($scriptHtmlOptions);
- $scriptBatches[$key]['htmlOptions']=$scriptHtmlOptions;
- $scriptBatches[$key]['scripts'][]=$scriptContent;
- }
- foreach($scriptBatches as $scriptBatch)
- if(!empty($scriptBatch['scripts']))
- $html.=CHtml::script(implode("\n",$scriptBatch['scripts']),$scriptBatch['htmlOptions'])."\n";
- return $html;
- }
- public function renderCoreScripts()
- {
- if($this->coreScripts===null)
- return;
- $cssFiles=array();
- $jsFiles=array();
- foreach($this->coreScripts as $name=>$package)
- {
- $baseUrl=$this->getPackageBaseUrl($name);
- if(!empty($package['js']))
- {
- foreach($package['js'] as $js)
- $jsFiles[$baseUrl.'/'.$js]=$baseUrl.'/'.$js;
- }
- if(!empty($package['css']))
- {
- foreach($package['css'] as $css)
- $cssFiles[$baseUrl.'/'.$css]='';
- }
- }
- // merge in place
- if($cssFiles!==array())
- {
- foreach($this->cssFiles as $cssFile=>$media)
- $cssFiles[$cssFile]=$media;
- $this->cssFiles=$cssFiles;
- }
- if($jsFiles!==array())
- {
- if(isset($this->scriptFiles[$this->coreScriptPosition]))
- {
- foreach($this->scriptFiles[$this->coreScriptPosition] as $url => $value)
- $jsFiles[$url]=$value;
- }
- $this->scriptFiles[$this->coreScriptPosition]=$jsFiles;
- }
- }
- public function renderHead(&$output)
- {
- $html='';
- foreach($this->metaTags as $meta)
- $html.=CHtml::metaTag($meta['content'],null,null,$meta)."\n";
- foreach($this->linkTags as $link)
- $html.=CHtml::linkTag(null,null,null,null,$link)."\n";
- foreach($this->cssFiles as $url=>$media)
- $html.=CHtml::cssFile($url,$media)."\n";
- foreach($this->css as $css)
- $html.=CHtml::css($css[0],$css[1])."\n";
- if($this->enableJavaScript)
- {
- if(isset($this->scriptFiles[self::POS_HEAD]))
- {
- foreach($this->scriptFiles[self::POS_HEAD] as $scriptFileValueUrl=>$scriptFileValue)
- {
- if(is_array($scriptFileValue))
- $html.=CHtml::scriptFile($scriptFileValueUrl,$scriptFileValue)."\n";
- else
- $html.=CHtml::scriptFile($scriptFileValueUrl)."\n";
- }
- }
- if(isset($this->scripts[self::POS_HEAD]))
- $html.=$this->renderScriptBatch($this->scripts[self::POS_HEAD]);
- }
- if($html!=='')
- {
- $count=0;
- $output=preg_replace('/(<title\b[^>]*>|<\\/head\s*>)/is','<###head###>$1',$output,1,$count);
- if($count)
- $output=str_replace('<###head###>',$html,$output);
- else
- $output=$html.$output;
- }
- }
- public function renderBodyBegin(&$output)
- {
- $html='';
- if(isset($this->scriptFiles[self::POS_BEGIN]))
- {
- foreach($this->scriptFiles[self::POS_BEGIN] as $scriptFileUrl=>$scriptFileValue)
- {
- if(is_array($scriptFileValue))
- $html.=CHtml::scriptFile($scriptFileUrl,$scriptFileValue)."\n";
- else
- $html.=CHtml::scriptFile($scriptFileUrl)."\n";
- }
- }
- if(isset($this->scripts[self::POS_BEGIN]))
- $html.=$this->renderScriptBatch($this->scripts[self::POS_BEGIN]);
- if($html!=='')
- {
- $count=0;
- $output=preg_replace('/(<body\b[^>]*>)/is','$1<###begin###>',$output,1,$count);
- if($count)
- $output=str_replace('<###begin###>',$html,$output);
- else
- $output=$html.$output;
- }
- }
- public function renderBodyEnd(&$output)
- {
- if(!isset($this->scriptFiles[self::POS_END]) && !isset($this->scripts[self::POS_END])
- && !isset($this->scripts[self::POS_READY]) && !isset($this->scripts[self::POS_LOAD]))
- return;
- $fullPage=0;
- $output=preg_replace('/(<\\/body\s*>)/is','<###end###>$1',$output,1,$fullPage);
- $html='';
- if(isset($this->scriptFiles[self::POS_END]))
- {
- foreach($this->scriptFiles[self::POS_END] as $scriptFileUrl=>$scriptFileValue)
- {
- if(is_array($scriptFileValue))
- $html.=CHtml::scriptFile($scriptFileUrl,$scriptFileValue)."\n";
- else
- $html.=CHtml::scriptFile($scriptFileUrl)."\n";
- }
- }
- $scripts=isset($this->scripts[self::POS_END]) ? $this->scripts[self::POS_END] : array();
- if(isset($this->scripts[self::POS_READY]))
- {
- if($fullPage)
- $scripts[]="jQuery(function($) {\n".implode("\n",$this->scripts[self::POS_READY])."\n});";
- else
- $scripts[]=implode("\n",$this->scripts[self::POS_READY]);
- }
- if(isset($this->scripts[self::POS_LOAD]))
- {
- if($fullPage)
- $scripts[]="jQuery(window).on('load',function() {\n".implode("\n",$this->scripts[self::POS_LOAD])."\n});";
- else
- $scripts[]=implode("\n",$this->scripts[self::POS_LOAD]);
- }
- if(!empty($scripts))
- $html.=$this->renderScriptBatch($scripts);
- if($fullPage)
- $output=str_replace('<###end###>',$html,$output);
- else
- $output=$output.$html;
- }
- public function getCoreScriptUrl()
- {
- if($this->_baseUrl!==null)
- return $this->_baseUrl;
- else
- return $this->_baseUrl=Yii::app()->getAssetManager()->publish(YII_PATH.'/web/js/source');
- }
- public function setCoreScriptUrl($value)
- {
- $this->_baseUrl=$value;
- }
- public function getPackageBaseUrl($name)
- {
- if(!isset($this->coreScripts[$name]))
- return false;
- $package=$this->coreScripts[$name];
- if(isset($package['baseUrl']))
- {
- $baseUrl=$package['baseUrl'];
- if($baseUrl==='' || $baseUrl[0]!=='/' && strpos($baseUrl,'://')===false)
- $baseUrl=Yii::app()->getRequest()->getBaseUrl().'/'.$baseUrl;
- $baseUrl=rtrim($baseUrl,'/');
- }
- elseif(isset($package['basePath']))
- $baseUrl=Yii::app()->getAssetManager()->publish(Yii::getPathOfAlias($package['basePath']));
- else
- $baseUrl=$this->getCoreScriptUrl();
- return $this->coreScripts[$name]['baseUrl']=$baseUrl;
- }
- public function registerPackage($name)
- {
- return $this->registerCoreScript($name);
- }
- public function registerCoreScript($name)
- {
- if(isset($this->coreScripts[$name]))
- return $this;
- if(isset($this->packages[$name]))
- $package=$this->packages[$name];
- else
- {
- if($this->corePackages===null)
- $this->corePackages=require(YII_PATH.'/web/js/packages.php');
- if(isset($this->corePackages[$name]))
- $package=$this->corePackages[$name];
- }
- if(isset($package))
- {
- if(!empty($package['depends']))
- {
- foreach($package['depends'] as $p)
- $this->registerCoreScript($p);
- }
- $this->coreScripts[$name]=$package;
- $this->hasScripts=true;
- $params=func_get_args();
- $this->recordCachingAction('clientScript','registerCoreScript',$params);
- }
- elseif(YII_DEBUG)
- throw new CException('There is no CClientScript package: '.$name);
- else
- Yii::log('There is no CClientScript package: '.$name,CLogger::LEVEL_WARNING,'system.web.CClientScript');
- return $this;
- }
- public function registerCssFile($url,$media='')
- {
- $this->hasScripts=true;
- $this->cssFiles[$url]=$media;
- $params=func_get_args();
- $this->recordCachingAction('clientScript','registerCssFile',$params);
- return $this;
- }
- public function registerCss($id,$css,$media='')
- {
- $this->hasScripts=true;
- $this->css[$id]=array($css,$media);
- $params=func_get_args();
- $this->recordCachingAction('clientScript','registerCss',$params);
- return $this;
- }
- public function registerScriptFile($url,$position=null,array $htmlOptions=array())
- {
- if($position===null)
- $position=$this->defaultScriptFilePosition;
- $this->hasScripts=true;
- if(empty($htmlOptions))
- $value=$url;
- else
- {
- $value=$htmlOptions;
- $value['src']=$url;
- }
- $this->scriptFiles[$position][$url]=$value;
- $params=func_get_args();
- $this->recordCachingAction('clientScript','registerScriptFile',$params);
- return $this;
- }
- public function registerScript($id,$script,$position=null,array $htmlOptions=array())
- {
- if($position===null)
- $position=$this->defaultScriptPosition;
- $this->hasScripts=true;
- if(empty($htmlOptions))
- $scriptValue=$script;
- else
- {
- if($position==self::POS_LOAD || $position==self::POS_READY)
- throw new CException(Yii::t('yii','Script HTML options are not allowed for "CClientScript::POS_LOAD" and "CClientScript::POS_READY".'));
- $scriptValue=$htmlOptions;
- $scriptValue['content']=$script;
- }
- $this->scripts[$position][$id]=$scriptValue;
- if($position===self::POS_READY || $position===self::POS_LOAD)
- $this->registerCoreScript('jquery');
- $params=func_get_args();
- $this->recordCachingAction('clientScript','registerScript',$params);
- return $this;
- }
- public function registerMetaTag($content,$name=null,$httpEquiv=null,$options=array(),$id=null)
- {
- $this->hasScripts=true;
- if($name!==null)
- $options['name']=$name;
- if($httpEquiv!==null)
- $options['http-equiv']=$httpEquiv;
- $options['content']=$content;
- $this->metaTags[null===$id?count($this->metaTags):$id]=$options;
- $params=func_get_args();
- $this->recordCachingAction('clientScript','registerMetaTag',$params);
- return $this;
- }
- public function registerLinkTag($relation=null,$type=null,$href=null,$media=null,$options=array())
- {
- $this->hasScripts=true;
- if($relation!==null)
- $options['rel']=$relation;
- if($type!==null)
- $options['type']=$type;
- if($href!==null)
- $options['href']=$href;
- if($media!==null)
- $options['media']=$media;
- $this->linkTags[serialize($options)]=$options;
- $params=func_get_args();
- $this->recordCachingAction('clientScript','registerLinkTag',$params);
- return $this;
- }
- public function isCssFileRegistered($url)
- {
- return isset($this->cssFiles[$url]);
- }
- public function isCssRegistered($id)
- {
- return isset($this->css[$id]);
- }
- public function isScriptFileRegistered($url,$position=self::POS_HEAD)
- {
- return isset($this->scriptFiles[$position][$url]);
- }
- public function isScriptRegistered($id,$position=self::POS_READY)
- {
- return isset($this->scripts[$position][$id]);
- }
- protected function recordCachingAction($context,$method,$params)
- {
- if(($controller=Yii::app()->getController())!==null)
- $controller->recordCachingAction($context,$method,$params);
- }
- public function addPackage($name,$definition)
- {
- $this->packages[$name]=$definition;
- return $this;
- }
- }
- class CList extends CComponent implements IteratorAggregate,ArrayAccess,Countable
- {
- private $_d=array();
- private $_c=0;
- private $_r=false;
- public function __construct($data=null,$readOnly=false)
- {
- if($data!==null)
- $this->copyFrom($data);
- $this->setReadOnly($readOnly);
- }
- public function getReadOnly()
- {
- return $this->_r;
- }
- protected function setReadOnly($value)
- {
- $this->_r=$value;
- }
- public function getIterator()
- {
- return new CListIterator($this->_d);
- }
- public function count()
- {
- return $this->getCount();
- }
- public function getCount()
- {
- return $this->_c;
- }
- public function itemAt($index)
- {
- if(isset($this->_d[$index]))
- return $this->_d[$index];
- elseif($index>=0 && $index<$this->_c) // in case the value is null
- return $this->_d[$index];
- else
- throw new CException(Yii::t('yii','List index "{index}" is out of bound.',
- array('{index}'=>$index)));
- }
- public function add($item)
- {
- $this->insertAt($this->_c,$item);
- return $this->_c-1;
- }
- public function insertAt($index,$item)
- {
- if(!$this->_r)
- {
- if($index===$this->_c)
- $this->_d[$this->_c++]=$item;
- elseif($index>=0 && $index<$this->_c)
- {
- array_splice($this->_d,$index,0,array($item));
- $this->_c++;
- }
- else
- throw new CException(Yii::t('yii','List index "{index}" is out of bound.',
- array('{index}'=>$index)));
- }
- else
- throw new CException(Yii::t('yii','The list is read only.'));
- }
- public function remove($item)
- {
- if(($index=$this->indexOf($item))>=0)
- {
- $this->removeAt($index);
- return $index;
- }
- else
- return false;
- }
- public function removeAt($index)
- {
- if(!$this->_r)
- {
- if($index>=0 && $index<$this->_c)
- {
- $this->_c--;
- if($index===$this->_c)
- return array_pop($this->_d);
- else
- {
- $item=$this->_d[$index];
- array_splice($this->_d,$index,1);
- return $item;
- }
- }
- else
- throw new CException(Yii::t('yii','List index "{index}" is out of bound.',
- array('{index}'=>$index)));
- }
- else
- throw new CException(Yii::t('yii','The list is read only.'));
- }
- public function clear()
- {
- for($i=$this->_c-1;$i>=0;--$i)
- $this->removeAt($i);
- }
- public function contains($item)
- {
- return $this->indexOf($item)>=0;
- }
- public function indexOf($item)
- {
- if(($index=array_search($item,$this->_d,true))!==false)
- return $index;
- else
- return -1;
- }
- public function toArray()
- {
- return $this->_d;
- }
- public function copyFrom($data)
- {
- if(is_array($data) || ($data instanceof Traversable))
- {
- if($this->_c>0)
- $this->clear();
- if($data instanceof CList)
- $data=$data->_d;
- foreach($data as $item)
- $this->add($item);
- }
- elseif($data!==null)
- throw new CException(Yii::t('yii','List data must be an array or an object implementing Traversable.'));
- }
- public function mergeWith($data)
- {
- if(is_array($data) || ($data instanceof Traversable))
- {
- if($data instanceof CList)
- $data=$data->_d;
- foreach($data as $item)
- $this->add($item);
- }
- elseif($data!==null)
- throw new CException(Yii::t('yii','List data must be an array or an object implementing Traversable.'));
- }
- public function offsetExists($offset)
- {
- return ($offset>=0 && $offset<$this->_c);
- }
- public function offsetGet($offset)
- {
- return $this->itemAt($offset);
- }
- public function offsetSet($offset,$item)
- {
- if($offset===null || $offset===$this->_c)
- $this->insertAt($this->_c,$item);
- else
- {
- $this->removeAt($offset);
- $this->insertAt($offset,$item);
- }
- }
- public function offsetUnset($offset)
- {
- $this->removeAt($offset);
- }
- }
- class CFilterChain extends CList
- {
- public $controller;
- public $action;
- public $filterIndex=0;
- public function __construct($controller,$action)
- {
- $this->controller=$controller;
- $this->action=$action;
- }
- public static function create($controller,$action,$filters)
- {
- $chain=new CFilterChain($controller,$action);
- $actionID=$action->getId();
- foreach($filters as $filter)
- {
- if(is_string($filter)) // filterName [+|- action1 action2]
- {
- if(($pos=strpos($filter,'+'))!==false || ($pos=strpos($filter,'-'))!==false)
- {
- $matched=preg_match("/\b{$actionID}\b/i",substr($filter,$pos+1))>0;
- if(($filter[$pos]==='+')===$matched)
- $filter=CInlineFilter::create($controller,trim(substr($filter,0,$pos)));
- }
- else
- $filter=CInlineFilter::create($controller,$filter);
- }
- elseif(is_array($filter)) // array('path.to.class [+|- action1, action2]','param1'=>'value1',...)
- {
- if(!isset($filter[0]))
- throw new CException(Yii::t('yii','The first element in a filter configuration must be the filter class.'));
- $filterClass=$filter[0];
- unset($filter[0]);
- if(($pos=strpos($filterClass,'+'))!==false || ($pos=strpos($filterClass,'-'))!==false)
- {
- $matched=preg_match("/\b{$actionID}\b/i",substr($filterClass,$pos+1))>0;
- if(($filterClass[$pos]==='+')===$matched)
- $filterClass=trim(substr($filterClass,0,$pos));
- else
- continue;
- }
- $filter['class']=$filterClass;
- $filter=Yii::createComponent($filter);
- }
- if(is_object($filter))
- {
- $filter->init();
- $chain->add($filter);
- }
- }
- return $chain;
- }
- public function insertAt($index,$item)
- {
- if($item instanceof IFilter)
- parent::insertAt($index,$item);
- else
- throw new CException(Yii::t('yii','CFilterChain can only take objects implementing the IFilter interface.'));
- }
- public function run()
- {
- if($this->offsetExists($this->filterIndex))
- {
- $filter=$this->itemAt($this->filterIndex++);
- $filter->filter($this);
- }
- else
- $this->controller->runAction($this->action);
- }
- }
- class CFilter extends CComponent implements IFilter
- {
- public function filter($filterChain)
- {
- if($this->preFilter($filterChain))
- {
- $filterChain->run();
- $this->postFilter($filterChain);
- }
- }
- public function init()
- {
- }
- protected function preFilter($filterChain)
- {
- return true;
- }
- protected function postFilter($filterChain)
- {
- }
- }
- class CInlineFilter extends CFilter
- {
- public $name;
- public static function create($controller,$filterName)
- {
- if(method_exists($controller,'filter'.$filterName))
- {
- $filter=new CInlineFilter;
- $filter->name=$filterName;
- return $filter;
- }
- else
- throw new CException(Yii::t('yii','Filter "{filter}" is invalid. Controller "{class}" does not have the filter method "filter{filter}".',
- array('{filter}'=>$filterName, '{class}'=>get_class($controller))));
- }
- public function filter($filterChain)
- {
- $method='filter'.$this->name;
- $filterChain->controller->$method($filterChain);
- }
- }
- class CAccessControlFilter extends CFilter
- {
- public $message;
- private $_rules=array();
- public function getRules()
- {
- return $this->_rules;
- }
- public function setRules($rules)
- {
- foreach($rules as $rule)
- {
- if(is_array($rule) && isset($rule[0]))
- {
- $r=new CAccessRule;
- $r->allow=$rule[0]==='allow';
- foreach(array_slice($rule,1) as $name=>$value)
- {
- if($name==='expression' || $name==='roles' || $name==='message' || $name==='deniedCallback')
- $r->$name=$value;
- else
- $r->$name=array_map('strtolower',$value);
- }
- $this->_rules[]=$r;
- }
- }
- }
- protected function preFilter($filterChain)
- {
- $app=Yii::app();
- $request=$app->getRequest();
- $user=$app->getUser();
- $verb=$request->getRequestType();
- $ip=$request->getUserHostAddress();
- foreach($this->getRules() as $rule)
- {
- if(($allow=$rule->isUserAllowed($user,$filterChain->controller,$filterChain->action,$ip,$verb))>0) // allowed
- break;
- elseif($allow<0) // denied
- {
- if(isset($rule->deniedCallback))
- call_user_func($rule->deniedCallback, $rule);
- else
- $this->accessDenied($user,$this->resolveErrorMessage($rule));
- return false;
- }
- }
- return true;
- }
- protected function resolveErrorMessage($rule)
- {
- if($rule->message!==null)
- return $rule->message;
- elseif($this->message!==null)
- return $this->message;
- else
- return Yii::t('yii','You are not authorized to perform this action.');
- }
- protected function accessDenied($user,$message)
- {
- if($user->getIsGuest())
- $user->loginRequired();
- else
- throw new CHttpException(403,$message);
- }
- }
- class CAccessRule extends CComponent
- {
- public $allow;
- public $actions;
- public $controllers;
- public $users;
- public $roles;
- public $ips;
- public $verbs;
- public $expression;
- public $message;
- public $deniedCallback;
- public function isUserAllowed($user,$controller,$action,$ip,$verb)
- {
- if($this->isActionMatched($action)
- && $this->isUserMatched($user)
- && $this->isRoleMatched($user)
- && $this->isIpMatched($ip)
- && $this->isVerbMatched($verb)
- && $this->isControllerMatched($controller)
- && $this->isExpressionMatched($user))
- return $this->allow ? 1 : -1;
- else
- return 0;
- }
- protected function isActionMatched($action)
- {
- return empty($this->actions) || in_array(strtolower($action->getId()),$this->actions);
- }
- protected function isControllerMatched($controller)
- {
- return empty($this->controllers) || in_array(strtolower($controller->getUniqueId()),$this->controllers);
- }
- protected function isUserMatched($user)
- {
- if(empty($this->users))
- return true;
- foreach($this->users as $u)
- {
- if($u==='*')
- return true;
- elseif($u==='?' && $user->getIsGuest())
- return true;
- elseif($u==='@' && !$user->getIsGuest())
- return true;
- elseif(!strcasecmp($u,$user->getName()))
- return true;
- }
- return false;
- }
- protected function isRoleMatched($user)
- {
- if(empty($this->roles))
- return true;
- foreach($this->roles as $key=>$role)
- {
- if(is_numeric($key))
- {
- if($user->checkAccess($role))
- return true;
- }
- else
- {
- if($user->checkAccess($key,$role))
- return true;
- }
- }
- return false;
- }
- protected function isIpMatched($ip)
- {
- if(empty($this->ips))
- return true;
- foreach($this->ips as $rule)
- {
- if($rule==='*' || $rule===$ip || (($pos=strpos($rule,'*'))!==false && !strncmp($ip,$rule,$pos)))
- return true;
- }
- return false;
- }
- protected function isVerbMatched($verb)
- {
- return empty($this->verbs) || in_array(strtolower($verb),$this->verbs);
- }
- protected function isExpressionMatched($user)
- {
- if($this->expression===null)
- return true;
- else
- return $this->evaluateExpression($this->expression, array('user'=>$user));
- }
- }
- abstract class CModel extends CComponent implements IteratorAggregate, ArrayAccess
- {
- private $_errors=array(); // attribute name => array of errors
- private $_validators; // validators
- private $_scenario=''; // scenario
- abstract public function attributeNames();
- public function rules()
- {
- return array();
- }
- public function behaviors()
- {
- return array();
- }
- public function attributeLabels()
- {
- return array();
- }
- public function validate($attributes=null, $clearErrors=true)
- {
- if($clearErrors)
- $this->clearErrors();
- if($this->beforeValidate())
- {
- foreach($this->getValidators() as $validator)
- $validator->validate($this,$attributes);
- $this->afterValidate();
- return !$this->hasErrors();
- }
- else
- return false;
- }
- protected function afterConstruct()
- {
- if($this->hasEventHandler('onAfterConstruct'))
- $this->onAfterConstruct(new CEvent($this));
- }
- protected function beforeValidate()
- {
- $event=new CModelEvent($this);
- $this->onBeforeValidate($event);
- return $event->isValid;
- }
- protected function afterValidate()
- {
- $this->onAfterValidate(new CEvent($this));
- }
- public function onAfterConstruct($event)
- {
- $this->raiseEvent('onAfterConstruct',$event);
- }
- public function onBeforeValidate($event)
- {
- $this->raiseEvent('onBeforeValidate',$event);
- }
- public function onAfterValidate($event)
- {
- $this->raiseEvent('onAfterValidate',$event);
- }
- public function getValidatorList()
- {
- if($this->_validators===null)
- $this->_validators=$this->createValidators();
- return $this->_validators;
- }
- public function getValidators($attribute=null)
- {
- if($this->_validators===null)
- $this->_validators=$this->createValidators();
- $validators=array();
- $scenario=$this->getScenario();
- foreach($this->_validators as $validator)
- {
- if($validator->applyTo($scenario))
- {
- if($attribute===null || in_array($attribute,$validator->attributes,true))
- $validators[]=$validator;
- }
- }
- return $validators;
- }
- public function createValidators()
- {
- $validators=new CList;
- foreach($this->rules() as $rule)
- {
- if(isset($rule[0],$rule[1])) // attributes, validator name
- $validators->add(CValidator::createValidator($rule[1],$this,$rule[0],array_slice($rule,2)));
- else
- throw new CException(Yii::t('yii','{class} has an invalid validation rule. The rule must specify attributes to be validated and the validator name.',
- array('{class}'=>get_class($this))));
- }
- return $validators;
- }
- public function isAttributeRequired($attribute)
- {
- foreach($this->getValidators($attribute) as $validator)
- {
- if($validator instanceof CRequiredValidator)
- return true;
- }
- return false;
- }
- public function isAttributeSafe($attribute)
- {
- $attributes=$this->getSafeAttributeNames();
- return in_array($attribute,$attributes);
- }
- public function getAttributeLabel($attribute)
- {
- $labels=$this->attributeLabels();
- if(isset($labels[$attribute]))
- return $labels[$attribute];
- else
- return $this->generateAttributeLabel($attribute);
- }
- public function hasErrors($attribute=null)
- {
- if($attribute===null)
- return $this->_errors!==array();
- else
- return isset($this->_errors[$attribute]);
- }
- public function getErrors($attribute=null)
- {
- if($attribute===null)
- return $this->_errors;
- else
- return isset($this->_errors[$attribute]) ? $this->_errors[$attribute] : array();
- }
- public function getError($attribute)
- {
- return isset($this->_errors[$attribute]) ? reset($this->_errors[$attribute]) : null;
- }
- public function addError($attribute,$error)
- {
- $this->_errors[$attribute][]=$error;
- }
- public function addErrors($errors)
- {
- foreach($errors as $attribute=>$error)
- {
- if(is_array($error))
- {
- foreach($error as $e)
- $this->addError($attribute, $e);
- }
- else
- $this->addError($attribute, $error);
- }
- }
- public function clearErrors($attribute=null)
- {
- if($attribute===null)
- $this->_errors=array();
- else
- unset($this->_errors[$attribute]);
- }
- public function generateAttributeLabel($name)
- {
- return ucwords(trim(strtolower(str_replace(array('-','_','.'),' ',preg_replace('/(?<![A-Z])[A-Z]/', ' \0', $name)))));
- }
- public function getAttributes($names=null)
- {
- $values=array();
- foreach($this->attributeNames() as $name)
- $values[$name]=$this->$name;
- if(is_array($names))
- {
- $values2=array();
- foreach($names as $name)
- $values2[$name]=isset($values[$name]) ? $values[$name] : null;
- return $values2;
- }
- else
- return $values;
- }
- public function setAttributes($values,$safeOnly=true)
- {
- if(!is_array($values))
- return;
- $attributes=array_flip($safeOnly ? $this->getSafeAttributeNames() : $this->attributeNames());
- foreach($values as $name=>$value)
- {
- if(isset($attributes[$name]))
- $this->$name=$value;
- elseif($safeOnly)
- $this->onUnsafeAttribute($name,$value);
- }
- }
- public function unsetAttributes($names=null)
- {
- if($names===null)
- $names=$this->attributeNames();
- foreach($names as $name)
- $this->$name=null;
- }
- public function onUnsafeAttribute($name,$value)
- {
- if(YII_DEBUG)
- Yii::log(Yii::t('yii','Failed to set unsafe attribute "{attribute}" of "{class}".',array('{attribute}'=>$name, '{class}'=>get_class($this))),CLogger::LEVEL_WARNING);
- }
- public function getScenario()
- {
- return $this->_scenario;
- }
- public function setScenario($value)
- {
- $this->_scenario=$value;
- }
- public function getSafeAttributeNames()
- {
- $attributes=array();
- $unsafe=array();
- foreach($this->getValidators() as $validator)
- {
- if(!$validator->safe)
- {
- foreach($validator->attributes as $name)
- $unsafe[]=$name;
- }
- else
- {
- foreach($validator->attributes as $name)
- $attributes[$name]=true;
- }
- }
- foreach($unsafe as $name)
- unset($attributes[$name]);
- return array_keys($attributes);
- }
- public function getIterator()
- {
- $attributes=$this->getAttributes();
- return new CMapIterator($attributes);
- }
- public function offsetExists($offset)
- {
- return property_exists($this,$offset);
- }
- public function offsetGet($offset)
- {
- return $this->$offset;
- }
- public function offsetSet($offset,$item)
- {
- $this->$offset=$item;
- }
- public function offsetUnset($offset)
- {
- unset($this->$offset);
- }
- }
- abstract class CActiveRecord extends CModel
- {
- const BELONGS_TO='CBelongsToRelation';
- const HAS_ONE='CHasOneRelation';
- const HAS_MANY='CHasManyRelation';
- const MANY_MANY='CManyManyRelation';
- const STAT='CStatRelation';
- public static $db;
- private static $_models=array(); // class name => model
- private static $_md=array(); // class name => meta data
- private $_new=false; // whether this instance is new or not
- private $_attributes=array(); // attribute name => attribute value
- private $_related=array(); // attribute name => related objects
- private $_c; // query criteria (used by finder only)
- private $_pk; // old primary key value
- private $_alias='t'; // the table alias being used for query
- public function __construct($scenario='insert')
- {
- if($scenario===null) // internally used by populateRecord() and model()
- return;
- $this->setScenario($scenario);
- $this->setIsNewRecord(true);
- $this->_attributes=$this->getMetaData()->attributeDefaults;
- $this->init();
- $this->attachBehaviors($this->behaviors());
- $this->afterConstruct();
- }
- public function init()
- {
- }
- public function cache($duration, $dependency=null, $queryCount=1)
- {
- $this->getDbConnection()->cache($duration, $dependency, $queryCount);
- return $this;
- }
- public function __sleep()
- {
- return array_keys((array)$this);
- }
- public function __get($name)
- {
- if(isset($this->_attributes[$name]))
- return $this->_attributes[$name];
- elseif(isset($this->getMetaData()->columns[$name]))
- return null;
- elseif(isset($this->_related[$name]))
- return $this->_related[$name];
- elseif(isset($this->getMetaData()->relations[$name]))
- return $this->getRelated($name);
- else
- return parent::__get($name);
- }
- public function __set($name,$value)
- {
- if($this->setAttribute($name,$value)===false)
- {
- if(isset($this->getMetaData()->relations[$name]))
- $this->_related[$name]=$value;
- else
- parent::__set($name,$value);
- }
- }
- public function __isset($name)
- {
- if(isset($this->_attributes[$name]))
- return true;
- elseif(isset($this->getMetaData()->columns[$name]))
- return false;
- elseif(isset($this->_related[$name]))
- return true;
- elseif(isset($this->getMetaData()->relations[$name]))
- return $this->getRelated($name)!==null;
- else
- return parent::__isset($name);
- }
- public function __unset($name)
- {
- if(isset($this->getMetaData()->columns[$name]))
- unset($this->_attributes[$name]);
- elseif(isset($this->getMetaData()->relations[$name]))
- unset($this->_related[$name]);
- else
- parent::__unset($name);
- }
- public function __call($name,$parameters)
- {
- if(isset($this->getMetaData()->relations[$name]))
- {
- if(empty($parameters))
- return $this->getRelated($name,false);
- else
- return $this->getRelated($name,false,$parameters[0]);
- }
- $scopes=$this->scopes();
- if(isset($scopes[$name]))
- {
- $this->getDbCriteria()->mergeWith($scopes[$name]);
- return $this;
- }
- return parent::__call($name,$parameters);
- }
- public function getRelated($name,$refresh=false,$params=array())
- {
- if(!$refresh && $params===array() && (isset($this->_related[$name]) || array_key_exists($name,$this->_related)))
- return $this->_related[$name];
- $md=$this->getMetaData();
- if(!isset($md->relations[$name]))
- throw new CDbException(Yii::t('yii','{class} does not have relation "{name}".',
- array('{class}'=>get_class($this), '{name}'=>$name)));
- $relation=$md->relations[$name];
- if($this->getIsNewRecord() && !$refresh && ($relation instanceof CHasOneRelation || $relation instanceof CHasManyRelation))
- return $relation instanceof CHasOneRelation ? null : array();
- if($params!==array()) // dynamic query
- {
- $exists=isset($this->_related[$name]) || array_key_exists($name,$this->_related);
- if($exists)
- $save=$this->_related[$name];
- if($params instanceof CDbCriteria)
- $params = $params->toArray();
- $r=array($name=>$params);
- }
- else
- $r=$name;
- unset($this->_related[$name]);
- $finder=$this->getActiveFinder($r);
- $finder->lazyFind($this);
- if(!isset($this->_related[$name]))
- {
- if($relation instanceof CHasManyRelation)
- $this->_related[$name]=array();
- elseif($relation instanceof CStatRelation)
- $this->_related[$name]=$relation->defaultValue;
- else
- $this->_related[$name]=null;
- }
- if($params!==array())
- {
- $results=$this->_related[$name];
- if($exists)
- $this->_related[$name]=$save;
- else
- unset($this->_related[$name]);
- return $results;
- }
- else
- return $this->_related[$name];
- }
- public function hasRelated($name)
- {
- return isset($this->_related[$name]) || array_key_exists($name,$this->_related);
- }
- public function getDbCriteria($createIfNull=true)
- {
- if($this->_c===null)
- {
- if(($c=$this->defaultScope())!==array() || $createIfNull)
- $this->_c=new CDbCriteria($c);
- }
- return $this->_c;
- }
- public function setDbCriteria($criteria)
- {
- $this->_c=$criteria;
- }
- public function defaultScope()
- {
- return array();
- }
- public function resetScope($resetDefault=true)
- {
- if($resetDefault)
- $this->_c=new CDbCriteria();
- else
- $this->_c=null;
- return $this;
- }
- public static function model($className=__CLASS__)
- {
- if(isset(self::$_models[$className]))
- return self::$_models[$className];
- else
- {
- $model=self::$_models[$className]=new $className(null);
- $model->attachBehaviors($model->behaviors());
- return $model;
- }
- }
- public function getMetaData()
- {
- $className=get_class($this);
- if(!array_key_exists($className,self::$_md))
- {
- self::$_md[$className]=null; // preventing recursive invokes of {@link getMetaData()} via {@link __get()}
- self::$_md[$className]=new CActiveRecordMetaData($this);
- }
- return self::$_md[$className];
- }
- public function refreshMetaData()
- {
- $className=get_class($this);
- if(array_key_exists($className,self::$_md))
- unset(self::$_md[$className]);
- }
- public function tableName()
- {
- $tableName = get_class($this);
- if(($pos=strrpos($tableName,'\\')) !== false)
- return substr($tableName,$pos+1);
- return $tableName;
- }
- public function primaryKey()
- {
- }
- public function relations()
- {
- return array();
- }
- public function scopes()
- {
- return array();
- }
- public function attributeNames()
- {
- return array_keys($this->getMetaData()->columns);
- }
- public function getAttributeLabel($attribute)
- {
- $labels=$this->attributeLabels();
- if(isset($labels[$attribute]))
- return $labels[$attribute];
- elseif(strpos($attribute,'.')!==false)
- {
- $segs=explode('.',$attribute);
- $name=array_pop($segs);
- $model=$this;
- foreach($segs as $seg)
- {
- $relations=$model->getMetaData()->relations;
- if(isset($relations[$seg]))
- $model=CActiveRecord::model($relations[$seg]->className);
- else
- break;
- }
- return $model->getAttributeLabel($name);
- }
- else
- return $this->generateAttributeLabel($attribute);
- }
- public function getDbConnection()
- {
- if(self::$db!==null)
- return self::$db;
- else
- {
- self::$db=Yii::app()->getDb();
- if(self::$db instanceof CDbConnection)
- return self::$db;
- else
- throw new CDbException(Yii::t('yii','Active Record requires a "db" CDbConnection application component.'));
- }
- }
- public function getActiveRelation($name)
- {
- return isset($this->getMetaData()->relations[$name]) ? $this->getMetaData()->relations[$name] : null;
- }
- public function getTableSchema()
- {
- return $this->getMetaData()->tableSchema;
- }
- public function getCommandBuilder()
- {
- return $this->getDbConnection()->getSchema()->getCommandBuilder();
- }
- public function hasAttribute($name)
- {
- return isset($this->getMetaData()->columns[$name]);
- }
- public function getAttribute($name)
- {
- if(property_exists($this,$name))
- return $this->$name;
- elseif(isset($this->_attributes[$name]))
- return $this->_attributes[$name];
- }
- public function setAttribute($name,$value)
- {
- if(property_exists($this,$name))
- $this->$name=$value;
- elseif(isset($this->getMetaData()->columns[$name]))
- $this->_attributes[$name]=$value;
- else
- return false;
- return true;
- }
- public function addRelatedRecord($name,$record,$index)
- {
- if($index!==false)
- {
- if(!isset($this->_related[$name]))
- $this->_related[$name]=array();
- if($record instanceof CActiveRecord)
- {
- if($index===true)
- $this->_related[$name][]=$record;
- else
- $this->_related[$name][$index]=$record;
- }
- }
- elseif(!isset($this->_related[$name]))
- $this->_related[$name]=$record;
- }
- public function getAttributes($names=true)
- {
- $attributes=$this->_attributes;
- foreach($this->getMetaData()->columns as $name=>$column)
- {
- if(property_exists($this,$name))
- $attributes[$name]=$this->$name;
- elseif($names===true && !isset($attributes[$name]))
- $attributes[$name]=null;
- }
- if(is_array($names))
- {
- $attrs=array();
- foreach($names as $name)
- {
- if(property_exists($this,$name))
- $attrs[$name]=$this->$name;
- else
- $attrs[$name]=isset($attributes[$name])?$attributes[$name]:null;
- }
- return $attrs;
- }
- else
- return $attributes;
- }
- public function save($runValidation=true,$attributes=null)
- {
- if(!$runValidation || $this->validate($attributes))
- return $this->getIsNewRecord() ? $this->insert($attributes) : $this->update($attributes);
- else
- return false;
- }
- public function getIsNewRecord()
- {
- return $this->_new;
- }
- public function setIsNewRecord($value)
- {
- $this->_new=$value;
- }
- public function onBeforeSave($event)
- {
- $this->raiseEvent('onBeforeSave',$event);
- }
- public function onAfterSave($event)
- {
- $this->raiseEvent('onAfterSave',$event);
- }
- public function onBeforeDelete($event)
- {
- $this->raiseEvent('onBeforeDelete',$event);
- }
- public function onAfterDelete($event)
- {
- $this->raiseEvent('onAfterDelete',$event);
- }
- public function onBeforeFind($event)
- {
- $this->raiseEvent('onBeforeFind',$event);
- }
- public function onAfterFind($event)
- {
- $this->raiseEvent('onAfterFind',$event);
- }
- public function getActiveFinder($with)
- {
- return new CActiveFinder($this,$with);
- }
- public function onBeforeCount($event)
- {
- $this->raiseEvent('onBeforeCount',$event);
- }
- protected function beforeSave()
- {
- if($this->hasEventHandler('onBeforeSave'))
- {
- $event=new CModelEvent($this);
- $this->onBeforeSave($event);
- return $event->isValid;
- }
- else
- return true;
- }
- protected function afterSave()
- {
- if($this->hasEventHandler('onAfterSave'))
- $this->onAfterSave(new CEvent($this));
- }
- protected function beforeDelete()
- {
- if($this->hasEventHandler('onBeforeDelete'))
- {
- $event=new CModelEvent($this);
- $this->onBeforeDelete($event);
- return $event->isValid;
- }
- else
- return true;
- }
- protected function afterDelete()
- {
- if($this->hasEventHandler('onAfterDelete'))
- $this->onAfterDelete(new CEvent($this));
- }
- protected function beforeFind()
- {
- if($this->hasEventHandler('onBeforeFind'))
- {
- $event=new CModelEvent($this);
- $this->onBeforeFind($event);
- }
- }
- protected function beforeCount()
- {
- if($this->hasEventHandler('onBeforeCount'))
- $this->onBeforeCount(new CEvent($this));
- }
- protected function afterFind()
- {
- if($this->hasEventHandler('onAfterFind'))
- $this->onAfterFind(new CEvent($this));
- }
- public function beforeFindInternal()
- {
- $this->beforeFind();
- }
- public function afterFindInternal()
- {
- $this->afterFind();
- }
- public function insert($attributes=null)
- {
- if(!$this->getIsNewRecord())
- throw new CDbException(Yii::t('yii','The active record cannot be inserted to database because it is not new.'));
- if($this->beforeSave())
- {
- $builder=$this->getCommandBuilder();
- $table=$this->getTableSchema();
- $command=$builder->createInsertCommand($table,$this->getAttributes($attributes));
- if($command->execute())
- {
- $primaryKey=$table->primaryKey;
- if($table->sequenceName!==null)
- {
- if(is_string($primaryKey) && $this->$primaryKey===null)
- $this->$primaryKey=$builder->getLastInsertID($table);
- elseif(is_array($primaryKey))
- {
- foreach($primaryKey as $pk)
- {
- if($this->$pk===null)
- {
- $this->$pk=$builder->getLastInsertID($table);
- break;
- }
- }
- }
- }
- $this->_pk=$this->getPrimaryKey();
- $this->afterSave();
- $this->setIsNewRecord(false);
- $this->setScenario('update');
- return true;
- }
- }
- return false;
- }
- public function update($attributes=null)
- {
- if($this->getIsNewRecord())
- throw new CDbException(Yii::t('yii','The active record cannot be updated because it is new.'));
- if($this->beforeSave())
- {
- if($this->_pk===null)
- $this->_pk=$this->getPrimaryKey();
- $this->updateByPk($this->getOldPrimaryKey(),$this->getAttributes($attributes));
- $this->_pk=$this->getPrimaryKey();
- $this->afterSave();
- return true;
- }
- else
- return false;
- }
- public function saveAttributes($attributes)
- {
- if(!$this->getIsNewRecord())
- {
- $values=array();
- foreach($attributes as $name=>$value)
- {
- if(is_integer($name))
- $values[$value]=$this->$value;
- else
- $values[$name]=$this->$name=$value;
- }
- if($this->_pk===null)
- $this->_pk=$this->getPrimaryKey();
- if($this->updateByPk($this->getOldPrimaryKey(),$values)>0)
- {
- $this->_pk=$this->getPrimaryKey();
- return true;
- }
- else
- return false;
- }
- else
- throw new CDbException(Yii::t('yii','The active record cannot be updated because it is new.'));
- }
- public function saveCounters($counters)
- {
- $builder=$this->getCommandBuilder();
- $table=$this->getTableSchema();
- $criteria=$builder->createPkCriteria($table,$this->getOldPrimaryKey());
- $command=$builder->createUpdateCounterCommand($this->getTableSchema(),$counters,$criteria);
- if($command->execute())
- {
- foreach($counters as $name=>$value)
- $this->$name=$this->$name+$value;
- return true;
- }
- else
- return false;
- }
- public function delete()
- {
- if(!$this->getIsNewRecord())
- {
- if($this->beforeDelete())
- {
- $result=$this->deleteByPk($this->getPrimaryKey())>0;
- $this->afterDelete();
- return $result;
- }
- else
- return false;
- }
- else
- throw new CDbException(Yii::t('yii','The active record cannot be deleted because it is new.'));
- }
- public function refresh()
- {
- if(($record=$this->findByPk($this->getPrimaryKey()))!==null)
- {
- $this->_attributes=array();
- $this->_related=array();
- foreach($this->getMetaData()->columns as $name=>$column)
- {
- if(property_exists($this,$name))
- $this->$name=$record->$name;
- else
- $this->_attributes[$name]=$record->$name;
- }
- return true;
- }
- else
- return false;
- }
- public function equals($record)
- {
- return $this->tableName()===$record->tableName() && $this->getPrimaryKey()===$record->getPrimaryKey();
- }
- public function getPrimaryKey()
- {
- $table=$this->getTableSchema();
- if(is_string($table->primaryKey))
- return $this->{$table->primaryKey};
- elseif(is_array($table->primaryKey))
- {
- $values=array();
- foreach($table->primaryKey as $name)
- $values[$name]=$this->$name;
- return $values;
- }
- else
- return null;
- }
- public function setPrimaryKey($value)
- {
- $this->_pk=$this->getPrimaryKey();
- $table=$this->getTableSchema();
- if(is_string($table->primaryKey))
- $this->{$table->primaryKey}=$value;
- elseif(is_array($table->primaryKey))
- {
- foreach($table->primaryKey as $name)
- $this->$name=$value[$name];
- }
- }
- public function getOldPrimaryKey()
- {
- return $this->_pk;
- }
- public function setOldPrimaryKey($value)
- {
- $this->_pk=$value;
- }
- protected function query($criteria,$all=false)
- {
- $this->beforeFind();
- $this->applyScopes($criteria);
- if(empty($criteria->with))
- {
- if(!$all)
- $criteria->limit=1;
- $command=$this->getCommandBuilder()->createFindCommand($this->getTableSchema(),$criteria);
- return $all ? $this->populateRecords($command->queryAll(), true, $criteria->index) : $this->populateRecord($command->queryRow());
- }
- else
- {
- $finder=$this->getActiveFinder($criteria->with);
- return $finder->query($criteria,$all);
- }
- }
- public function applyScopes(&$criteria)
- {
- if(!empty($criteria->scopes))
- {
- $scs=$this->scopes();
- $c=$this->getDbCriteria();
- foreach((array)$criteria->scopes as $k=>$v)
- {
- if(is_integer($k))
- {
- if(is_string($v))
- {
- if(isset($scs[$v]))
- {
- $c->mergeWith($scs[$v],true);
- continue;
- }
- $scope=$v;
- $params=array();
- }
- elseif(is_array($v))
- {
- $scope=key($v);
- $params=current($v);
- }
- }
- elseif(is_string($k))
- {
- $scope=$k;
- $params=$v;
- }
- call_user_func_array(array($this,$scope),(array)$params);
- }
- }
- if(isset($c) || ($c=$this->getDbCriteria(false))!==null)
- {
- $c->mergeWith($criteria);
- $criteria=$c;
- $this->resetScope(false);
- }
- }
- public function getTableAlias($quote=false, $checkScopes=true)
- {
- if($checkScopes && ($criteria=$this->getDbCriteria(false))!==null && $criteria->alias!='')
- $alias=$criteria->alias;
- else
- $alias=$this->_alias;
- return $quote ? $this->getDbConnection()->getSchema()->quoteTableName($alias) : $alias;
- }
- public function setTableAlias($alias)
- {
- $this->_alias=$alias;
- }
- public function find($condition='',$params=array())
- {
- $criteria=$this->getCommandBuilder()->createCriteria($condition,$params);
- return $this->query($criteria);
- }
- public function findAll($condition='',$params=array())
- {
- $criteria=$this->getCommandBuilder()->createCriteria($condition,$params);
- return $this->query($criteria,true);
- }
- public function findByPk($pk,$condition='',$params=array())
- {
- $prefix=$this->getTableAlias(true).'.';
- $criteria=$this->getCommandBuilder()->createPkCriteria($this->getTableSchema(),$pk,$condition,$params,$prefix);
- return $this->query($criteria);
- }
- public function findAllByPk($pk,$condition='',$params=array())
- {
- $prefix=$this->getTableAlias(true).'.';
- $criteria=$this->getCommandBuilder()->createPkCriteria($this->getTableSchema(),$pk,$condition,$params,$prefix);
- return $this->query($criteria,true);
- }
- public function findByAttributes($attributes,$condition='',$params=array())
- {
- $prefix=$this->getTableAlias(true).'.';
- $criteria=$this->getCommandBuilder()->createColumnCriteria($this->getTableSchema(),$attributes,$condition,$params,$prefix);
- return $this->query($criteria);
- }
- public function findAllByAttributes($attributes,$condition='',$params=array())
- {
- $prefix=$this->getTableAlias(true).'.';
- $criteria=$this->getCommandBuilder()->createColumnCriteria($this->getTableSchema(),$attributes,$condition,$params,$prefix);
- return $this->query($criteria,true);
- }
- public function findBySql($sql,$params=array())
- {
- $this->beforeFind();
- if(($criteria=$this->getDbCriteria(false))!==null && !empty($criteria->with))
- {
- $this->resetScope(false);
- $finder=$this->getActiveFinder($criteria->with);
- return $finder->findBySql($sql,$params);
- }
- else
- {
- $command=$this->getCommandBuilder()->createSqlCommand($sql,$params);
- return $this->populateRecord($command->queryRow());
- }
- }
- public function findAllBySql($sql,$params=array())
- {
- $this->beforeFind();
- if(($criteria=$this->getDbCriteria(false))!==null && !empty($criteria->with))
- {
- $this->resetScope(false);
- $finder=$this->getActiveFinder($criteria->with);
- return $finder->findAllBySql($sql,$params);
- }
- else
- {
- $command=$this->getCommandBuilder()->createSqlCommand($sql,$params);
- return $this->populateRecords($command->queryAll());
- }
- }
- public function count($condition='',$params=array())
- {
- $this->beforeCount();
- $builder=$this->getCommandBuilder();
- $criteria=$builder->createCriteria($condition,$params);
- $this->applyScopes($criteria);
- if(empty($criteria->with))
- return $builder->createCountCommand($this->getTableSchema(),$criteria)->queryScalar();
- else
- {
- $finder=$this->getActiveFinder($criteria->with);
- return $finder->count($criteria);
- }
- }
- public function countByAttributes($attributes,$condition='',$params=array())
- {
- $prefix=$this->getTableAlias(true).'.';
- $builder=$this->getCommandBuilder();
- $this->beforeCount();
- $criteria=$builder->createColumnCriteria($this->getTableSchema(),$attributes,$condition,$params,$prefix);
- $this->applyScopes($criteria);
- if(empty($criteria->with))
- return $builder->createCountCommand($this->getTableSchema(),$criteria)->queryScalar();
- else
- {
- $finder=$this->getActiveFinder($criteria->with);
- return $finder->count($criteria);
- }
- }
- public function countBySql($sql,$params=array())
- {
- $this->beforeCount();
- return $this->getCommandBuilder()->createSqlCommand($sql,$params)->queryScalar();
- }
- public function exists($condition='',$params=array())
- {
- $builder=$this->getCommandBuilder();
- $criteria=$builder->createCriteria($condition,$params);
- $table=$this->getTableSchema();
- $criteria->select='1';
- $criteria->limit=1;
- $this->applyScopes($criteria);
- if(empty($criteria->with))
- return $builder->createFindCommand($table,$criteria,$this->getTableAlias(false, false))->queryRow()!==false;
- else
- {
- $criteria->select='*';
- $finder=$this->getActiveFinder($criteria->with);
- return $finder->count($criteria)>0;
- }
- }
- public function with()
- {
- if(func_num_args()>0)
- {
- $with=func_get_args();
- if(is_array($with[0])) // the parameter is given as an array
- $with=$with[0];
- if(!empty($with))
- $this->getDbCriteria()->mergeWith(array('with'=>$with));
- }
- return $this;
- }
- public function together()
- {
- $this->getDbCriteria()->together=true;
- return $this;
- }
- public function updateByPk($pk,$attributes,$condition='',$params=array())
- {
- $builder=$this->getCommandBuilder();
- $table=$this->getTableSchema();
- $criteria=$builder->createPkCriteria($table,$pk,$condition,$params);
- $command=$builder->createUpdateCommand($table,$attributes,$criteria);
- return $command->execute();
- }
- public function updateAll($attributes,$condition='',$params=array())
- {
- $builder=$this->getCommandBuilder();
- $criteria=$builder->createCriteria($condition,$params);
- $command=$builder->createUpdateCommand($this->getTableSchema(),$attributes,$criteria);
- return $command->execute();
- }
- public function updateCounters($counters,$condition='',$params=array())
- {
- $builder=$this->getCommandBuilder();
- $criteria=$builder->createCriteria($condition,$params);
- $command=$builder->createUpdateCounterCommand($this->getTableSchema(),$counters,$criteria);
- return $command->execute();
- }
- public function deleteByPk($pk,$condition='',$params=array())
- {
- $builder=$this->getCommandBuilder();
- $criteria=$builder->createPkCriteria($this->getTableSchema(),$pk,$condition,$params);
- $command=$builder->createDeleteCommand($this->getTableSchema(),$criteria);
- return $command->execute();
- }
- public function deleteAll($condition='',$params=array())
- {
- $builder=$this->getCommandBuilder();
- $criteria=$builder->createCriteria($condition,$params);
- $command=$builder->createDeleteCommand($this->getTableSchema(),$criteria);
- return $command->execute();
- }
- public function deleteAllByAttributes($attributes,$condition='',$params=array())
- {
- $builder=$this->getCommandBuilder();
- $table=$this->getTableSchema();
- $criteria=$builder->createColumnCriteria($table,$attributes,$condition,$params);
- $command=$builder->createDeleteCommand($table,$criteria);
- return $command->execute();
- }
- public function populateRecord($attributes,$callAfterFind=true)
- {
- if($attributes!==false)
- {
- $record=$this->instantiate($attributes);
- $record->setScenario('update');
- $record->init();
- $md=$record->getMetaData();
- foreach($attributes as $name=>$value)
- {
- if(property_exists($record,$name))
- $record->$name=$value;
- elseif(isset($md->columns[$name]))
- $record->_attributes[$name]=$value;
- }
- $record->_pk=$record->getPrimaryKey();
- $record->attachBehaviors($record->behaviors());
- if($callAfterFind)
- $record->afterFind();
- return $record;
- }
- else
- return null;
- }
- public function populateRecords($data,$callAfterFind=true,$index=null)
- {
- $records=array();
- foreach($data as $attributes)
- {
- if(($record=$this->populateRecord($attributes,$callAfterFind))!==null)
- {
- if($index===null)
- $records[]=$record;
- else
- $records[$record->$index]=$record;
- }
- }
- return $records;
- }
- protected function instantiate($attributes)
- {
- $class=get_class($this);
- $model=new $class(null);
- return $model;
- }
- public function offsetExists($offset)
- {
- return $this->__isset($offset);
- }
- }
- class CBaseActiveRelation extends CComponent
- {
- public $name;
- public $className;
- public $foreignKey;
- public $select='*';
- public $condition='';
- public $params=array();
- public $group='';
- public $join='';
- public $joinOptions='';
- public $having='';
- public $order='';
- public function __construct($name,$className,$foreignKey,$options=array())
- {
- $this->name=$name;
- $this->className=$className;
- $this->foreignKey=$foreignKey;
- foreach($options as $name=>$value)
- $this->$name=$value;
- }
- public function mergeWith($criteria,$fromScope=false)
- {
- if($criteria instanceof CDbCriteria)
- $criteria=$criteria->toArray();
- if(isset($criteria['select']) && $this->select!==$criteria['select'])
- {
- if($this->select==='*')
- $this->select=$criteria['select'];
- elseif($criteria['select']!=='*')
- {
- $select1=is_string($this->select)?preg_split('/\s*,\s*/',trim($this->select),-1,PREG_SPLIT_NO_EMPTY):$this->select;
- $select2=is_string($criteria['select'])?preg_split('/\s*,\s*/',trim($criteria['select']),-1,PREG_SPLIT_NO_EMPTY):$criteria['select'];
- $this->select=array_merge($select1,array_diff($select2,$select1));
- }
- }
- if(isset($criteria['condition']) && $this->condition!==$criteria['condition'])
- {
- if($this->condition==='')
- $this->condition=$criteria['condition'];
- elseif($criteria['condition']!=='')
- $this->condition="({$this->condition}) AND ({$criteria['condition']})";
- }
- if(isset($criteria['params']) && $this->params!==$criteria['params'])
- $this->params=array_merge($this->params,$criteria['params']);
- if(isset($criteria['order']) && $this->order!==$criteria['order'])
- {
- if($this->order==='')
- $this->order=$criteria['order'];
- elseif($criteria['order']!=='')
- $this->order=$criteria['order'].', '.$this->order;
- }
- if(isset($criteria['group']) && $this->group!==$criteria['group'])
- {
- if($this->group==='')
- $this->group=$criteria['group'];
- elseif($criteria['group']!=='')
- $this->group.=', '.$criteria['group'];
- }
- if(isset($criteria['join']) && $this->join!==$criteria['join'])
- {
- if($this->join==='')
- $this->join=$criteria['join'];
- elseif($criteria['join']!=='')
- $this->join.=' '.$criteria['join'];
- }
- if(isset($criteria['having']) && $this->having!==$criteria['having'])
- {
- if($this->having==='')
- $this->having=$criteria['having'];
- elseif($criteria['having']!=='')
- $this->having="({$this->having}) AND ({$criteria['having']})";
- }
- }
- }
- class CStatRelation extends CBaseActiveRelation
- {
- public $select='COUNT(*)';
- public $defaultValue=0;
- public $scopes;
- public function mergeWith($criteria,$fromScope=false)
- {
- if($criteria instanceof CDbCriteria)
- $criteria=$criteria->toArray();
- parent::mergeWith($criteria,$fromScope);
- if(isset($criteria['defaultValue']))
- $this->defaultValue=$criteria['defaultValue'];
- }
- }
- class CActiveRelation extends CBaseActiveRelation
- {
- public $joinType='LEFT OUTER JOIN';
- public $on='';
- public $alias;
- public $with=array();
- public $together;
- public $scopes;
- public $through;
- public function mergeWith($criteria,$fromScope=false)
- {
- if($criteria instanceof CDbCriteria)
- $criteria=$criteria->toArray();
- if($fromScope)
- {
- if(isset($criteria['condition']) && $this->on!==$criteria['condition'])
- {
- if($this->on==='')
- $this->on=$criteria['condition'];
- elseif($criteria['condition']!=='')
- $this->on="({$this->on}) AND ({$criteria['condition']})";
- }
- unset($criteria['condition']);
- }
- parent::mergeWith($criteria);
- if(isset($criteria['joinType']))
- $this->joinType=$criteria['joinType'];
- if(isset($criteria['on']) && $this->on!==$criteria['on'])
- {
- if($this->on==='')
- $this->on=$criteria['on'];
- elseif($criteria['on']!=='')
- $this->on="({$this->on}) AND ({$criteria['on']})";
- }
- if(isset($criteria['with']))
- $this->with=$criteria['with'];
- if(isset($criteria['alias']))
- $this->alias=$criteria['alias'];
- if(isset($criteria['together']))
- $this->together=$criteria['together'];
- }
- }
- class CBelongsToRelation extends CActiveRelation
- {
- }
- class CHasOneRelation extends CActiveRelation
- {
- }
- class CHasManyRelation extends CActiveRelation
- {
- public $limit=-1;
- public $offset=-1;
- public $index;
- public function mergeWith($criteria,$fromScope=false)
- {
- if($criteria instanceof CDbCriteria)
- $criteria=$criteria->toArray();
- parent::mergeWith($criteria,$fromScope);
- if(isset($criteria['limit']) && $criteria['limit']>0)
- $this->limit=$criteria['limit'];
- if(isset($criteria['offset']) && $criteria['offset']>=0)
- $this->offset=$criteria['offset'];
- if(isset($criteria['index']))
- $this->index=$criteria['index'];
- }
- }
- class CManyManyRelation extends CHasManyRelation
- {
- private $_junctionTableName=null;
- private $_junctionForeignKeys=null;
- public function getJunctionTableName()
- {
- if ($this->_junctionTableName===null)
- $this->initJunctionData();
- return $this->_junctionTableName;
- }
- public function getJunctionForeignKeys()
- {
- if ($this->_junctionForeignKeys===null)
- $this->initJunctionData();
- return $this->_junctionForeignKeys;
- }
- private function initJunctionData()
- {
- if(!preg_match('/^\s*(.*?)\((.*)\)\s*$/',$this->foreignKey,$matches))
- throw new CDbException(Yii::t('yii','The relation "{relation}" in active record class "{class}" is specified with an invalid foreign key. The format of the foreign key must be "joinTable(fk1,fk2,...)".',
- array('{class}'=>$this->className,'{relation}'=>$this->name)));
- $this->_junctionTableName=$matches[1];
- $this->_junctionForeignKeys=preg_split('/\s*,\s*/',$matches[2],-1,PREG_SPLIT_NO_EMPTY);
- }
- }
- class CActiveRecordMetaData
- {
- public $tableSchema;
- public $columns;
- public $relations=array();
- public $attributeDefaults=array();
- private $_modelClassName;
- public function __construct($model)
- {
- $this->_modelClassName=get_class($model);
- $tableName=$model->tableName();
- if(($table=$model->getDbConnection()->getSchema()->getTable($tableName))===null)
- throw new CDbException(Yii::t('yii','The table "{table}" for active record class "{class}" cannot be found in the database.',
- array('{class}'=>$this->_modelClassName,'{table}'=>$tableName)));
- if(($modelPk=$model->primaryKey())!==null || $table->primaryKey===null)
- {
- $table->primaryKey=$modelPk;
- if(is_string($table->primaryKey) && isset($table->columns[$table->primaryKey]))
- $table->columns[$table->primaryKey]->isPrimaryKey=true;
- elseif(is_array($table->primaryKey))
- {
- foreach($table->primaryKey as $name)
- {
- if(isset($table->columns[$name]))
- $table->columns[$name]->isPrimaryKey=true;
- }
- }
- }
- $this->tableSchema=$table;
- $this->columns=$table->columns;
- foreach($table->columns as $name=>$column)
- {
- if(!$column->isPrimaryKey && $column->defaultValue!==null)
- $this->attributeDefaults[$name]=$column->defaultValue;
- }
- foreach($model->relations() as $name=>$config)
- {
- $this->addRelation($name,$config);
- }
- }
- public function addRelation($name,$config)
- {
- if(isset($config[0],$config[1],$config[2])) // relation class, AR class, FK
- $this->relations[$name]=new $config[0]($name,$config[1],$config[2],array_slice($config,3));
- else
- throw new CDbException(Yii::t('yii','Active record "{class}" has an invalid configuration for relation "{relation}". It must specify the relation type, the related active record class and the foreign key.', array('{class}'=>$this->_modelClassName,'{relation}'=>$name)));
- }
- public function hasRelation($name)
- {
- return isset($this->relations[$name]);
- }
- public function removeRelation($name)
- {
- unset($this->relations[$name]);
- }
- }
- class CDbConnection extends CApplicationComponent
- {
- public $connectionString;
- public $username='';
- public $password='';
- public $schemaCachingDuration=0;
- public $schemaCachingExclude=array();
- public $schemaCacheID='cache';
- public $queryCachingDuration=0;
- public $queryCachingDependency;
- public $queryCachingCount=0;
- public $queryCacheID='cache';
- public $autoConnect=true;
- public $charset;
- public $emulatePrepare;
- public $enableParamLogging=false;
- public $enableProfiling=false;
- public $tablePrefix;
- public $initSQLs;
- public $driverMap=array(
- 'cubrid'=>'CCubridSchema', // CUBRID
- 'pgsql'=>'CPgsqlSchema', // PostgreSQL
- 'mysqli'=>'CMysqlSchema', // MySQL
- 'mysql'=>'CMysqlSchema', // MySQL,MariaDB
- 'sqlite'=>'CSqliteSchema', // sqlite 3
- 'sqlite2'=>'CSqliteSchema', // sqlite 2
- 'mssql'=>'CMssqlSchema', // Mssql driver on windows hosts
- 'dblib'=>'CMssqlSchema', // dblib drivers on linux (and maybe others os) hosts
- 'sqlsrv'=>'CMssqlSchema', // Mssql
- 'oci'=>'COciSchema', // Oracle driver
- );
- public $pdoClass = 'PDO';
- private $_driverName;
- private $_attributes=array();
- private $_active=false;
- private $_pdo;
- private $_transaction;
- private $_schema;
- public function __construct($dsn='',$username='',$password='')
- {
- $this->connectionString=$dsn;
- $this->username=$username;
- $this->password=$password;
- }
- public function __sleep()
- {
- $this->close();
- return array_keys(get_object_vars($this));
- }
- public static function getAvailableDrivers()
- {
- return PDO::getAvailableDrivers();
- }
- public function init()
- {
- parent::init();
- if($this->autoConnect)
- $this->setActive(true);
- }
- public function getActive()
- {
- return $this->_active;
- }
- public function setActive($value)
- {
- if($value!=$this->_active)
- {
- if($value)
- $this->open();
- else
- $this->close();
- }
- }
- public function cache($duration, $dependency=null, $queryCount=1)
- {
- $this->queryCachingDuration=$duration;
- $this->queryCachingDependency=$dependency;
- $this->queryCachingCount=$queryCount;
- return $this;
- }
- protected function open()
- {
- if($this->_pdo===null)
- {
- if(empty($this->connectionString))
- throw new CDbException('CDbConnection.connectionString cannot be empty.');
- try
- {
- $this->_pdo=$this->createPdoInstance();
- $this->initConnection($this->_pdo);
- $this->_active=true;
- }
- catch(PDOException $e)
- {
- if(YII_DEBUG)
- {
- throw new CDbException('CDbConnection failed to open the DB connection: '.
- $e->getMessage(),(int)$e->getCode(),$e->errorInfo);
- }
- else
- {
- Yii::log($e->getMessage(),CLogger::LEVEL_ERROR,'exception.CDbException');
- throw new CDbException('CDbConnection failed to open the DB connection.',(int)$e->getCode(),$e->errorInfo);
- }
- }
- }
- }
- protected function close()
- {
- $this->_pdo=null;
- $this->_active=false;
- $this->_schema=null;
- }
- protected function createPdoInstance()
- {
- $pdoClass=$this->pdoClass;
- if(($driver=$this->getDriverName())!==null)
- {
- if($driver==='mssql' || $driver==='dblib')
- $pdoClass='CMssqlPdoAdapter';
- elseif($driver==='sqlsrv')
- $pdoClass='CMssqlSqlsrvPdoAdapter';
- }
- if(!class_exists($pdoClass))
- throw new CDbException(Yii::t('yii','CDbConnection is unable to find PDO class "{className}". Make sure PDO is installed correctly.',
- array('{className}'=>$pdoClass)));
- @$instance=new $pdoClass($this->connectionString,$this->username,$this->password,$this->_attributes);
- if(!$instance)
- throw new CDbException(Yii::t('yii','CDbConnection failed to open the DB connection.'));
- return $instance;
- }
- protected function initConnection($pdo)
- {
- $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- if($this->emulatePrepare!==null && constant('PDO::ATTR_EMULATE_PREPARES'))
- $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,$this->emulatePrepare);
- if($this->charset!==null)
- {
- $driver=strtolower($pdo->getAttribute(PDO::ATTR_DRIVER_NAME));
- if(in_array($driver,array('pgsql','mysql','mysqli')))
- $pdo->exec('SET NAMES '.$pdo->quote($this->charset));
- }
- if($this->initSQLs!==null)
- {
- foreach($this->initSQLs as $sql)
- $pdo->exec($sql);
- }
- }
- public function getPdoInstance()
- {
- return $this->_pdo;
- }
- public function createCommand($query=null)
- {
- $this->setActive(true);
- return new CDbCommand($this,$query);
- }
- public function getCurrentTransaction()
- {
- if($this->_transaction!==null)
- {
- if($this->_transaction->getActive())
- return $this->_transaction;
- }
- return null;
- }
- public function beginTransaction()
- {
- $this->setActive(true);
- $this->_pdo->beginTransaction();
- return $this->_transaction=new CDbTransaction($this);
- }
- public function getSchema()
- {
- if($this->_schema!==null)
- return $this->_schema;
- else
- {
- $driver=$this->getDriverName();
- if(isset($this->driverMap[$driver]))
- return $this->_schema=Yii::createComponent($this->driverMap[$driver], $this);
- else
- throw new CDbException(Yii::t('yii','CDbConnection does not support reading schema for {driver} database.',
- array('{driver}'=>$driver)));
- }
- }
- public function getCommandBuilder()
- {
- return $this->getSchema()->getCommandBuilder();
- }
- public function getLastInsertID($sequenceName='')
- {
- $this->setActive(true);
- return $this->_pdo->lastInsertId($sequenceName);
- }
- public function quoteValue($str)
- {
- if(is_int($str) || is_float($str))
- return $str;
- $this->setActive(true);
- if(($value=$this->_pdo->quote($str))!==false)
- return $value;
- else // the driver doesn't support quote (e.g. oci)
- return "'" . addcslashes(str_replace("'", "''", $str), "\000\n\r\\\032") . "'";
- }
- public function quoteTableName($name)
- {
- return $this->getSchema()->quoteTableName($name);
- }
- public function quoteColumnName($name)
- {
- return $this->getSchema()->quoteColumnName($name);
- }
- public function getPdoType($type)
- {
- static $map=array
- (
- 'boolean'=>PDO::PARAM_BOOL,
- 'integer'=>PDO::PARAM_INT,
- 'string'=>PDO::PARAM_STR,
- 'resource'=>PDO::PARAM_LOB,
- 'NULL'=>PDO::PARAM_NULL,
- );
- return isset($map[$type]) ? $map[$type] : PDO::PARAM_STR;
- }
- public function getColumnCase()
- {
- return $this->getAttribute(PDO::ATTR_CASE);
- }
- public function setColumnCase($value)
- {
- $this->setAttribute(PDO::ATTR_CASE,$value);
- }
- public function getNullConversion()
- {
- return $this->getAttribute(PDO::ATTR_ORACLE_NULLS);
- }
- public function setNullConversion($value)
- {
- $this->setAttribute(PDO::ATTR_ORACLE_NULLS,$value);
- }
- public function getAutoCommit()
- {
- return $this->getAttribute(PDO::ATTR_AUTOCOMMIT);
- }
- public function setAutoCommit($value)
- {
- $this->setAttribute(PDO::ATTR_AUTOCOMMIT,$value);
- }
- public function getPersistent()
- {
- return $this->getAttribute(PDO::ATTR_PERSISTENT);
- }
- public function setPersistent($value)
- {
- return $this->setAttribute(PDO::ATTR_PERSISTENT,$value);
- }
- public function getDriverName()
- {
- if($this->_driverName!==null)
- return $this->_driverName;
- elseif(($pos=strpos($this->connectionString,':'))!==false)
- return $this->_driverName=strtolower(substr($this->connectionString,0,$pos));
- //return $this->getAttribute(PDO::ATTR_DRIVER_NAME);
- }
- public function setDriverName($driverName)
- {
- $this->_driverName=strtolower($driverName);
- }
- public function getClientVersion()
- {
- return $this->getAttribute(PDO::ATTR_CLIENT_VERSION);
- }
- public function getConnectionStatus()
- {
- return $this->getAttribute(PDO::ATTR_CONNECTION_STATUS);
- }
- public function getPrefetch()
- {
- return $this->getAttribute(PDO::ATTR_PREFETCH);
- }
- public function getServerInfo()
- {
- return $this->getAttribute(PDO::ATTR_SERVER_INFO);
- }
- public function getServerVersion()
- {
- return $this->getAttribute(PDO::ATTR_SERVER_VERSION);
- }
- public function getTimeout()
- {
- return $this->getAttribute(PDO::ATTR_TIMEOUT);
- }
- public function getAttribute($name)
- {
- $this->setActive(true);
- return $this->_pdo->getAttribute($name);
- }
- public function setAttribute($name,$value)
- {
- if($this->_pdo instanceof PDO)
- $this->_pdo->setAttribute($name,$value);
- else
- $this->_attributes[$name]=$value;
- }
- public function getAttributes()
- {
- return $this->_attributes;
- }
- public function setAttributes($values)
- {
- foreach($values as $name=>$value)
- $this->_attributes[$name]=$value;
- }
- public function getStats()
- {
- $logger=Yii::getLogger();
- $timings=$logger->getProfilingResults(null,'system.db.CDbCommand.query');
- $count=count($timings);
- $time=array_sum($timings);
- $timings=$logger->getProfilingResults(null,'system.db.CDbCommand.execute');
- $count+=count($timings);
- $time+=array_sum($timings);
- return array($count,$time);
- }
- }
- abstract class CDbSchema extends CComponent
- {
- public $columnTypes=array();
- private $_tableNames=array();
- private $_tables=array();
- private $_connection;
- private $_builder;
- private $_cacheExclude=array();
- abstract protected function loadTable($name);
- public function __construct($conn)
- {
- $this->_connection=$conn;
- foreach($conn->schemaCachingExclude as $name)
- $this->_cacheExclude[$name]=true;
- }
- public function getDbConnection()
- {
- return $this->_connection;
- }
- public function getTable($name,$refresh=false)
- {
- if($refresh===false && isset($this->_tables[$name]))
- return $this->_tables[$name];
- else
- {
- if($this->_connection->tablePrefix!==null && strpos($name,'{{')!==false)
- $realName=preg_replace('/\{\{(.*?)\}\}/',$this->_connection->tablePrefix.'$1',$name);
- else
- $realName=$name;
- // temporarily disable query caching
- if($this->_connection->queryCachingDuration>0)
- {
- $qcDuration=$this->_connection->queryCachingDuration;
- $this->_connection->queryCachingDuration=0;
- }
- if(!isset($this->_cacheExclude[$name]) && ($duration=$this->_connection->schemaCachingDuration)>0 && $this->_connection->schemaCacheID!==false && ($cache=Yii::app()->getComponent($this->_connection->schemaCacheID))!==null)
- {
- $key='yii:dbschema'.$this->_connection->connectionString.':'.$this->_connection->username.':'.$name;
- $table=$cache->get($key);
- if($refresh===true || $table===false)
- {
- $table=$this->loadTable($realName);
- if($table!==null)
- $cache->set($key,$table,$duration);
- }
- $this->_tables[$name]=$table;
- }
- else
- $this->_tables[$name]=$table=$this->loadTable($realName);
- if(isset($qcDuration)) // re-enable query caching
- $this->_connection->queryCachingDuration=$qcDuration;
- return $table;
- }
- }
- public function getTables($schema='')
- {
- $tables=array();
- foreach($this->getTableNames($schema) as $name)
- {
- if(($table=$this->getTable($name))!==null)
- $tables[$name]=$table;
- }
- return $tables;
- }
- public function getTableNames($schema='')
- {
- if(!isset($this->_tableNames[$schema]))
- $this->_tableNames[$schema]=$this->findTableNames($schema);
- return $this->_tableNames[$schema];
- }
- public function getCommandBuilder()
- {
- if($this->_builder!==null)
- return $this->_builder;
- else
- return $this->_builder=$this->createCommandBuilder();
- }
- public function refresh()
- {
- if(($duration=$this->_connection->schemaCachingDuration)>0 && $this->_connection->schemaCacheID!==false && ($cache=Yii::app()->getComponent($this->_connection->schemaCacheID))!==null)
- {
- foreach(array_keys($this->_tables) as $name)
- {
- if(!isset($this->_cacheExclude[$name]))
- {
- $key='yii:dbschema'.$this->_connection->connectionString.':'.$this->_connection->username.':'.$name;
- $cache->delete($key);
- }
- }
- }
- $this->_tables=array();
- $this->_tableNames=array();
- $this->_builder=null;
- }
- public function quoteTableName($name)
- {
- if(strpos($name,'.')===false)
- return $this->quoteSimpleTableName($name);
- $parts=explode('.',$name);
- foreach($parts as $i=>$part)
- $parts[$i]=$this->quoteSimpleTableName($part);
- return implode('.',$parts);
- }
- public function quoteSimpleTableName($name)
- {
- return "'".$name."'";
- }
- public function quoteColumnName($name)
- {
- if(($pos=strrpos($name,'.'))!==false)
- {
- $prefix=$this->quoteTableName(substr($name,0,$pos)).'.';
- $name=substr($name,$pos+1);
- }
- else
- $prefix='';
- return $prefix . ($name==='*' ? $name : $this->quoteSimpleColumnName($name));
- }
- public function quoteSimpleColumnName($name)
- {
- return '"'.$name.'"';
- }
- public function compareTableNames($name1,$name2)
- {
- $name1=str_replace(array('"','`',"'"),'',$name1);
- $name2=str_replace(array('"','`',"'"),'',$name2);
- if(($pos=strrpos($name1,'.'))!==false)
- $name1=substr($name1,$pos+1);
- if(($pos=strrpos($name2,'.'))!==false)
- $name2=substr($name2,$pos+1);
- if($this->_connection->tablePrefix!==null)
- {
- if(strpos($name1,'{')!==false)
- $name1=$this->_connection->tablePrefix.str_replace(array('{','}'),'',$name1);
- if(strpos($name2,'{')!==false)
- $name2=$this->_connection->tablePrefix.str_replace(array('{','}'),'',$name2);
- }
- return $name1===$name2;
- }
- public function resetSequence($table,$value=null)
- {
- }
- public function checkIntegrity($check=true,$schema='')
- {
- }
- protected function createCommandBuilder()
- {
- return new CDbCommandBuilder($this);
- }
- protected function findTableNames($schema='')
- {
- throw new CDbException(Yii::t('yii','{class} does not support fetching all table names.',
- array('{class}'=>get_class($this))));
- }
- public function getColumnType($type)
- {
- if(isset($this->columnTypes[$type]))
- return $this->columnTypes[$type];
- elseif(($pos=strpos($type,' '))!==false)
- {
- $t=substr($type,0,$pos);
- return (isset($this->columnTypes[$t]) ? $this->columnTypes[$t] : $t).substr($type,$pos);
- }
- else
- return $type;
- }
- public function createTable($table,$columns,$options=null)
- {
- $cols=array();
- foreach($columns as $name=>$type)
- {
- if(is_string($name))
- $cols[]="\t".$this->quoteColumnName($name).' '.$this->getColumnType($type);
- else
- $cols[]="\t".$type;
- }
- $sql="CREATE TABLE ".$this->quoteTableName($table)." (\n".implode(",\n",$cols)."\n)";
- return $options===null ? $sql : $sql.' '.$options;
- }
- public function renameTable($table,$newName)
- {
- return 'RENAME TABLE ' . $this->quoteTableName($table) . ' TO ' . $this->quoteTableName($newName);
- }
- public function dropTable($table)
- {
- return "DROP TABLE ".$this->quoteTableName($table);
- }
- public function truncateTable($table)
- {
- return "TRUNCATE TABLE ".$this->quoteTableName($table);
- }
- public function addColumn($table,$column,$type)
- {
- return 'ALTER TABLE ' . $this->quoteTableName($table)
- . ' ADD ' . $this->quoteColumnName($column) . ' '
- . $this->getColumnType($type);
- }
- public function dropColumn($table,$column)
- {
- return "ALTER TABLE ".$this->quoteTableName($table)
- ." DROP COLUMN ".$this->quoteColumnName($column);
- }
- public function renameColumn($table,$name,$newName)
- {
- return "ALTER TABLE ".$this->quoteTableName($table)
- . " RENAME COLUMN ".$this->quoteColumnName($name)
- . " TO ".$this->quoteColumnName($newName);
- }
- public function alterColumn($table,$column,$type)
- {
- return 'ALTER TABLE ' . $this->quoteTableName($table) . ' CHANGE '
- . $this->quoteColumnName($column) . ' '
- . $this->quoteColumnName($column) . ' '
- . $this->getColumnType($type);
- }
- public function addForeignKey($name,$table,$columns,$refTable,$refColumns,$delete=null,$update=null)
- {
- if(is_string($columns))
- $columns=preg_split('/\s*,\s*/',$columns,-1,PREG_SPLIT_NO_EMPTY);
- foreach($columns as $i=>$col)
- $columns[$i]=$this->quoteColumnName($col);
- if(is_string($refColumns))
- $refColumns=preg_split('/\s*,\s*/',$refColumns,-1,PREG_SPLIT_NO_EMPTY);
- foreach($refColumns as $i=>$col)
- $refColumns[$i]=$this->quoteColumnName($col);
- $sql='ALTER TABLE '.$this->quoteTableName($table)
- .' ADD CONSTRAINT '.$this->quoteColumnName($name)
- .' FOREIGN KEY ('.implode(', ',$columns).')'
- .' REFERENCES '.$this->quoteTableName($refTable)
- .' ('.implode(', ',$refColumns).')';
- if($delete!==null)
- $sql.=' ON DELETE '.$delete;
- if($update!==null)
- $sql.=' ON UPDATE '.$update;
- return $sql;
- }
- public function dropForeignKey($name,$table)
- {
- return 'ALTER TABLE '.$this->quoteTableName($table)
- .' DROP CONSTRAINT '.$this->quoteColumnName($name);
- }
- public function createIndex($name,$table,$columns,$unique=false)
- {
- $cols=array();
- if(is_string($columns))
- $columns=preg_split('/\s*,\s*/',$columns,-1,PREG_SPLIT_NO_EMPTY);
- foreach($columns as $col)
- {
- if(strpos($col,'(')!==false)
- $cols[]=$col;
- else
- $cols[]=$this->quoteColumnName($col);
- }
- return ($unique ? 'CREATE UNIQUE INDEX ' : 'CREATE INDEX ')
- . $this->quoteTableName($name).' ON '
- . $this->quoteTableName($table).' ('.implode(', ',$cols).')';
- }
- public function dropIndex($name,$table)
- {
- return 'DROP INDEX '.$this->quoteTableName($name).' ON '.$this->quoteTableName($table);
- }
- public function addPrimaryKey($name,$table,$columns)
- {
- if(is_string($columns))
- $columns=preg_split('/\s*,\s*/',$columns,-1,PREG_SPLIT_NO_EMPTY);
- foreach($columns as $i=>$col)
- $columns[$i]=$this->quoteColumnName($col);
- return 'ALTER TABLE ' . $this->quoteTableName($table) . ' ADD CONSTRAINT '
- . $this->quoteColumnName($name) . ' PRIMARY KEY ('
- . implode(', ',$columns). ' )';
- }
- public function dropPrimaryKey($name,$table)
- {
- return 'ALTER TABLE ' . $this->quoteTableName($table) . ' DROP CONSTRAINT '
- . $this->quoteColumnName($name);
- }
- }
- class CSqliteSchema extends CDbSchema
- {
- public $columnTypes=array(
- 'pk' => 'integer PRIMARY KEY AUTOINCREMENT NOT NULL',
- 'bigpk' => 'integer PRIMARY KEY AUTOINCREMENT NOT NULL',
- 'string' => 'varchar(255)',
- 'text' => 'text',
- 'integer' => 'integer',
- 'bigint' => 'integer',
- 'float' => 'float',
- 'decimal' => 'decimal',
- 'datetime' => 'datetime',
- 'timestamp' => 'timestamp',
- 'time' => 'time',
- 'date' => 'date',
- 'binary' => 'blob',
- 'boolean' => 'tinyint(1)',
- 'money' => 'decimal(19,4)',
- );
- public function resetSequence($table,$value=null)
- {
- if($table->sequenceName===null)
- return;
- if($value!==null)
- $value=(int)($value)-1;
- else
- $value=(int)$this->getDbConnection()
- ->createCommand("SELECT MAX(`{$table->primaryKey}`) FROM {$table->rawName}")
- ->queryScalar();
- try
- {
- // it's possible that 'sqlite_sequence' does not exist
- $this->getDbConnection()
- ->createCommand("UPDATE sqlite_sequence SET seq='$value' WHERE name='{$table->name}'")
- ->execute();
- }
- catch(Exception $e)
- {
- }
- }
- public function checkIntegrity($check=true,$schema='')
- {
- $this->getDbConnection()->createCommand('PRAGMA foreign_keys='.(int)$check)->execute();
- }
- protected function findTableNames($schema='')
- {
- $sql="SELECT DISTINCT tbl_name FROM sqlite_master WHERE tbl_name<>'sqlite_sequence'";
- return $this->getDbConnection()->createCommand($sql)->queryColumn();
- }
- protected function createCommandBuilder()
- {
- return new CSqliteCommandBuilder($this);
- }
- protected function loadTable($name)
- {
- $table=new CDbTableSchema;
- $table->name=$name;
- $table->rawName=$this->quoteTableName($name);
- if($this->findColumns($table))
- {
- $this->findConstraints($table);
- return $table;
- }
- else
- return null;
- }
- protected function findColumns($table)
- {
- $sql="PRAGMA table_info({$table->rawName})";
- $columns=$this->getDbConnection()->createCommand($sql)->queryAll();
- if(empty($columns))
- return false;
- foreach($columns as $column)
- {
- $c=$this->createColumn($column);
- $table->columns[$c->name]=$c;
- if($c->isPrimaryKey)
- {
- if($table->primaryKey===null)
- $table->primaryKey=$c->name;
- elseif(is_string($table->primaryKey))
- $table->primaryKey=array($table->primaryKey,$c->name);
- else
- $table->primaryKey[]=$c->name;
- }
- }
- if(is_string($table->primaryKey) && !strncasecmp($table->columns[$table->primaryKey]->dbType,'int',3))
- {
- $table->sequenceName='';
- $table->columns[$table->primaryKey]->autoIncrement=true;
- }
- return true;
- }
- protected function findConstraints($table)
- {
- $foreignKeys=array();
- $sql="PRAGMA foreign_key_list({$table->rawName})";
- $keys=$this->getDbConnection()->createCommand($sql)->queryAll();
- foreach($keys as $key)
- {
- $column=$table->columns[$key['from']];
- $column->isForeignKey=true;
- $foreignKeys[$key['from']]=array($key['table'],$key['to']);
- }
- $table->foreignKeys=$foreignKeys;
- }
- protected function createColumn($column)
- {
- $c=new CSqliteColumnSchema;
- $c->name=$column['name'];
- $c->rawName=$this->quoteColumnName($c->name);
- $c->allowNull=!$column['notnull'];
- $c->isPrimaryKey=$column['pk']!=0;
- $c->isForeignKey=false;
- $c->comment=null; // SQLite does not support column comments at all
- $c->init(strtolower($column['type']),$column['dflt_value']);
- return $c;
- }
- public function renameTable($table, $newName)
- {
- return 'ALTER TABLE ' . $this->quoteTableName($table) . ' RENAME TO ' . $this->quoteTableName($newName);
- }
- public function truncateTable($table)
- {
- return "DELETE FROM ".$this->quoteTableName($table);
- }
- public function dropColumn($table, $column)
- {
- throw new CDbException(Yii::t('yii', 'Dropping DB column is not supported by SQLite.'));
- }
- public function renameColumn($table, $name, $newName)
- {
- throw new CDbException(Yii::t('yii', 'Renaming a DB column is not supported by SQLite.'));
- }
- public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete=null, $update=null)
- {
- throw new CDbException(Yii::t('yii', 'Adding a foreign key constraint to an existing table is not supported by SQLite.'));
- }
- public function dropForeignKey($name, $table)
- {
- throw new CDbException(Yii::t('yii', 'Dropping a foreign key constraint is not supported by SQLite.'));
- }
- public function alterColumn($table, $column, $type)
- {
- throw new CDbException(Yii::t('yii', 'Altering a DB column is not supported by SQLite.'));
- }
- public function dropIndex($name, $table)
- {
- return 'DROP INDEX '.$this->quoteTableName($name);
- }
- public function addPrimaryKey($name,$table,$columns)
- {
- throw new CDbException(Yii::t('yii', 'Adding a primary key after table has been created is not supported by SQLite.'));
- }
- public function dropPrimaryKey($name,$table)
- {
- throw new CDbException(Yii::t('yii', 'Removing a primary key after table has been created is not supported by SQLite.'));
- }
- }
- class CDbTableSchema extends CComponent
- {
- public $name;
- public $rawName;
- public $primaryKey;
- public $sequenceName;
- public $foreignKeys=array();
- public $columns=array();
- public function getColumn($name)
- {
- return isset($this->columns[$name]) ? $this->columns[$name] : null;
- }
- public function getColumnNames()
- {
- return array_keys($this->columns);
- }
- }
- class CDbCommand extends CComponent
- {
- public $params=array();
- private $_connection;
- private $_text;
- private $_statement;
- private $_paramLog=array();
- private $_query;
- private $_fetchMode = array(PDO::FETCH_ASSOC);
- public function __construct(CDbConnection $connection,$query=null)
- {
- $this->_connection=$connection;
- if(is_array($query))
- {
- foreach($query as $name=>$value)
- $this->$name=$value;
- }
- else
- $this->setText($query);
- }
- public function __sleep()
- {
- $this->_statement=null;
- return array_keys(get_object_vars($this));
- }
- public function setFetchMode($mode)
- {
- $params=func_get_args();
- $this->_fetchMode = $params;
- return $this;
- }
- public function reset()
- {
- $this->_text=null;
- $this->_query=null;
- $this->_statement=null;
- $this->_paramLog=array();
- $this->params=array();
- return $this;
- }
- public function getText()
- {
- if($this->_text=='' && !empty($this->_query))
- $this->setText($this->buildQuery($this->_query));
- return $this->_text;
- }
- public function setText($value)
- {
- if($this->_connection->tablePrefix!==null && $value!='')
- $this->_text=preg_replace('/{{(.*?)}}/',$this->_connection->tablePrefix.'\1',$value);
- else
- $this->_text=$value;
- $this->cancel();
- return $this;
- }
- public function getConnection()
- {
- return $this->_connection;
- }
- public function getPdoStatement()
- {
- return $this->_statement;
- }
- public function prepare()
- {
- if($this->_statement==null)
- {
- try
- {
- $this->_statement=$this->getConnection()->getPdoInstance()->prepare($this->getText());
- $this->_paramLog=array();
- }
- catch(Exception $e)
- {
- Yii::log('Error in preparing SQL: '.$this->getText(),CLogger::LEVEL_ERROR,'system.db.CDbCommand');
- $errorInfo=$e instanceof PDOException ? $e->errorInfo : null;
- throw new CDbException(Yii::t('yii','CDbCommand failed to prepare the SQL statement: {error}',
- array('{error}'=>$e->getMessage())),(int)$e->getCode(),$errorInfo);
- }
- }
- }
- public function cancel()
- {
- $this->_statement=null;
- }
- public function bindParam($name, &$value, $dataType=null, $length=null, $driverOptions=null)
- {
- $this->prepare();
- if($dataType===null)
- $this->_statement->bindParam($name,$value,$this->_connection->getPdoType(gettype($value)));
- elseif($length===null)
- $this->_statement->bindParam($name,$value,$dataType);
- elseif($driverOptions===null)
- $this->_statement->bindParam($name,$value,$dataType,$length);
- else
- $this->_statement->bindParam($name,$value,$dataType,$length,$driverOptions);
- $this->_paramLog[$name]=&$value;
- return $this;
- }
- public function bindValue($name, $value, $dataType=null)
- {
- $this->prepare();
- if($dataType===null)
- $this->_statement->bindValue($name,$value,$this->_connection->getPdoType(gettype($value)));
- else
- $this->_statement->bindValue($name,$value,$dataType);
- $this->_paramLog[$name]=$value;
- return $this;
- }
- public function bindValues($values)
- {
- $this->prepare();
- foreach($values as $name=>$value)
- {
- $this->_statement->bindValue($name,$value,$this->_connection->getPdoType(gettype($value)));
- $this->_paramLog[$name]=$value;
- }
- return $this;
- }
- public function execute($params=array())
- {
- if($this->_connection->enableParamLogging && ($pars=array_merge($this->_paramLog,$params))!==array())
- {
- $p=array();
- foreach($pars as $name=>$value)
- $p[$name]=$name.'='.var_export($value,true);
- $par='. Bound with ' .implode(', ',$p);
- }
- else
- $par='';
- try
- {
- if($this->_connection->enableProfiling)
- Yii::beginProfile('system.db.CDbCommand.execute('.$this->getText().$par.')','system.db.CDbCommand.execute');
- $this->prepare();
- if($params===array())
- $this->_statement->execute();
- else
- $this->_statement->execute($params);
- $n=$this->_statement->rowCount();
- if($this->_connection->enableProfiling)
- Yii::endProfile('system.db.CDbCommand.execute('.$this->getText().$par.')','system.db.CDbCommand.execute');
- return $n;
- }
- catch(Exception $e)
- {
- if($this->_connection->enableProfiling)
- Yii::endProfile('system.db.CDbCommand.execute('.$this->getText().$par.')','system.db.CDbCommand.execute');
- $errorInfo=$e instanceof PDOException ? $e->errorInfo : null;
- $message=$e->getMessage();
- Yii::log(Yii::t('yii','CDbCommand::execute() failed: {error}. The SQL statement executed was: {sql}.',
- array('{error}'=>$message, '{sql}'=>$this->getText().$par)),CLogger::LEVEL_ERROR,'system.db.CDbCommand');
- if(YII_DEBUG)
- $message.='. The SQL statement executed was: '.$this->getText().$par;
- throw new CDbException(Yii::t('yii','CDbCommand failed to execute the SQL statement: {error}',
- array('{error}'=>$message)),(int)$e->getCode(),$errorInfo);
- }
- }
- public function query($params=array())
- {
- return $this->queryInternal('',0,$params);
- }
- public function queryAll($fetchAssociative=true,$params=array())
- {
- return $this->queryInternal('fetchAll',$fetchAssociative ? $this->_fetchMode : PDO::FETCH_NUM, $params);
- }
- public function queryRow($fetchAssociative=true,$params=array())
- {
- return $this->queryInternal('fetch',$fetchAssociative ? $this->_fetchMode : PDO::FETCH_NUM, $params);
- }
- public function queryScalar($params=array())
- {
- $result=$this->queryInternal('fetchColumn',0,$params);
- if(is_resource($result) && get_resource_type($result)==='stream')
- return stream_get_contents($result);
- else
- return $result;
- }
- public function queryColumn($params=array())
- {
- return $this->queryInternal('fetchAll',array(PDO::FETCH_COLUMN, 0),$params);
- }
- private function queryInternal($method,$mode,$params=array())
- {
- $params=array_merge($this->params,$params);
- if($this->_connection->enableParamLogging && ($pars=array_merge($this->_paramLog,$params))!==array())
- {
- $p=array();
- foreach($pars as $name=>$value)
- $p[$name]=$name.'='.var_export($value,true);
- $par='. Bound with '.implode(', ',$p);
- }
- else
- $par='';
- if($this->_connection->queryCachingCount>0 && $method!==''
- && $this->_connection->queryCachingDuration>0
- && $this->_connection->queryCacheID!==false
- && ($cache=Yii::app()->getComponent($this->_connection->queryCacheID))!==null)
- {
- $this->_connection->queryCachingCount--;
- $cacheKey='yii:dbquery'.':'.$method.':'.$this->_connection->connectionString.':'.$this->_connection->username;
- $cacheKey.=':'.$this->getText().':'.serialize(array_merge($this->_paramLog,$params));
- if(($result=$cache->get($cacheKey))!==false)
- {
- return $result[0];
- }
- }
- try
- {
- if($this->_connection->enableProfiling)
- Yii::beginProfile('system.db.CDbCommand.query('.$this->getText().$par.')','system.db.CDbCommand.query');
- $this->prepare();
- if($params===array())
- $this->_statement->execute();
- else
- $this->_statement->execute($params);
- if($method==='')
- $result=new CDbDataReader($this);
- else
- {
- $mode=(array)$mode;
- call_user_func_array(array($this->_statement, 'setFetchMode'), $mode);
- $result=$this->_statement->$method();
- $this->_statement->closeCursor();
- }
- if($this->_connection->enableProfiling)
- Yii::endProfile('system.db.CDbCommand.query('.$this->getText().$par.')','system.db.CDbCommand.query');
- if(isset($cache,$cacheKey))
- $cache->set($cacheKey, array($result), $this->_connection->queryCachingDuration, $this->_connection->queryCachingDependency);
- return $result;
- }
- catch(Exception $e)
- {
- if($this->_connection->enableProfiling)
- Yii::endProfile('system.db.CDbCommand.query('.$this->getText().$par.')','system.db.CDbCommand.query');
- $errorInfo=$e instanceof PDOException ? $e->errorInfo : null;
- $message=$e->getMessage();
- Yii::log(Yii::t('yii','CDbCommand::{method}() failed: {error}. The SQL statement executed was: {sql}.',
- array('{method}'=>$method, '{error}'=>$message, '{sql}'=>$this->getText().$par)),CLogger::LEVEL_ERROR,'system.db.CDbCommand');
- if(YII_DEBUG)
- $message.='. The SQL statement executed was: '.$this->getText().$par;
- throw new CDbException(Yii::t('yii','CDbCommand failed to execute the SQL statement: {error}',
- array('{error}'=>$message)),(int)$e->getCode(),$errorInfo);
- }
- }
- public function buildQuery($query)
- {
- $sql=!empty($query['distinct']) ? 'SELECT DISTINCT' : 'SELECT';
- $sql.=' '.(!empty($query['select']) ? $query['select'] : '*');
- if(!empty($query['from']))
- $sql.="\nFROM ".$query['from'];
- if(!empty($query['join']))
- $sql.="\n".(is_array($query['join']) ? implode("\n",$query['join']) : $query['join']);
- if(!empty($query['where']))
- $sql.="\nWHERE ".$query['where'];
- if(!empty($query['group']))
- $sql.="\nGROUP BY ".$query['group'];
- if(!empty($query['having']))
- $sql.="\nHAVING ".$query['having'];
- if(!empty($query['union']))
- $sql.="\nUNION (\n".(is_array($query['union']) ? implode("\n) UNION (\n",$query['union']) : $query['union']) . ')';
- if(!empty($query['order']))
- $sql.="\nORDER BY ".$query['order'];
- $limit=isset($query['limit']) ? (int)$query['limit'] : -1;
- $offset=isset($query['offset']) ? (int)$query['offset'] : -1;
- if($limit>=0 || $offset>0)
- $sql=$this->_connection->getCommandBuilder()->applyLimit($sql,$limit,$offset);
- return $sql;
- }
- public function select($columns='*', $option='')
- {
- if(is_string($columns) && strpos($columns,'(')!==false)
- $this->_query['select']=$columns;
- else
- {
- if(!is_array($columns))
- $columns=preg_split('/\s*,\s*/',trim($columns),-1,PREG_SPLIT_NO_EMPTY);
- foreach($columns as $i=>$column)
- {
- if(is_object($column))
- $columns[$i]=(string)$column;
- elseif(strpos($column,'(')===false)
- {
- if(preg_match('/^(.*?)(?i:\s+as\s+|\s+)(.*)$/',$column,$matches))
- $columns[$i]=$this->_connection->quoteColumnName($matches[1]).' AS '.$this->_connection->quoteColumnName($matches[2]);
- else
- $columns[$i]=$this->_connection->quoteColumnName($column);
- }
- }
- $this->_query['select']=implode(', ',$columns);
- }
- if($option!='')
- $this->_query['select']=$option.' '.$this->_query['select'];
- return $this;
- }
- public function getSelect()
- {
- return isset($this->_query['select']) ? $this->_query['select'] : '';
- }
- public function setSelect($value)
- {
- $this->select($value);
- }
- public function selectDistinct($columns='*')
- {
- $this->_query['distinct']=true;
- return $this->select($columns);
- }
- public function getDistinct()
- {
- return isset($this->_query['distinct']) ? $this->_query['distinct'] : false;
- }
- public function setDistinct($value)
- {
- $this->_query['distinct']=$value;
- }
- public function from($tables)
- {
- if(is_string($tables) && strpos($tables,'(')!==false)
- $this->_query['from']=$tables;
- else
- {
- if(!is_array($tables))
- $tables=preg_split('/\s*,\s*/',trim($tables),-1,PREG_SPLIT_NO_EMPTY);
- foreach($tables as $i=>$table)
- {
- if(strpos($table,'(')===false)
- {
- if(preg_match('/^(.*?)(?i:\s+as\s+|\s+)(.*)$/',$table,$matches)) // with alias
- $tables[$i]=$this->_connection->quoteTableName($matches[1]).' '.$this->_connection->quoteTableName($matches[2]);
- else
- $tables[$i]=$this->_connection->quoteTableName($table);
- }
- }
- $this->_query['from']=implode(', ',$tables);
- }
- return $this;
- }
- public function getFrom()
- {
- return isset($this->_query['from']) ? $this->_query['from'] : '';
- }
- public function setFrom($value)
- {
- $this->from($value);
- }
- public function where($conditions, $params=array())
- {
- $this->_query['where']=$this->processConditions($conditions);
- foreach($params as $name=>$value)
- $this->params[$name]=$value;
- return $this;
- }
- public function andWhere($conditions,$params=array())
- {
- if(isset($this->_query['where']))
- $this->_query['where']=$this->processConditions(array('AND',$this->_query['where'],$conditions));
- else
- $this->_query['where']=$this->processConditions($conditions);
- foreach($params as $name=>$value)
- $this->params[$name]=$value;
- return $this;
- }
- public function orWhere($conditions,$params=array())
- {
- if(isset($this->_query['where']))
- $this->_query['where']=$this->processConditions(array('OR',$this->_query['where'],$conditions));
- else
- $this->_query['where']=$this->processConditions($conditions);
- foreach($params as $name=>$value)
- $this->params[$name]=$value;
- return $this;
- }
- public function getWhere()
- {
- return isset($this->_query['where']) ? $this->_query['where'] : '';
- }
- public function setWhere($value)
- {
- $this->where($value);
- }
- public function join($table, $conditions, $params=array())
- {
- return $this->joinInternal('join', $table, $conditions, $params);
- }
- public function getJoin()
- {
- return isset($this->_query['join']) ? $this->_query['join'] : '';
- }
- public function setJoin($value)
- {
- $this->_query['join']=$value;
- }
- public function leftJoin($table, $conditions, $params=array())
- {
- return $this->joinInternal('left join', $table, $conditions, $params);
- }
- public function rightJoin($table, $conditions, $params=array())
- {
- return $this->joinInternal('right join', $table, $conditions, $params);
- }
- public function crossJoin($table)
- {
- return $this->joinInternal('cross join', $table);
- }
- public function naturalJoin($table)
- {
- return $this->joinInternal('natural join', $table);
- }
- public function naturalLeftJoin($table)
- {
- return $this->joinInternal('natural left join', $table);
- }
- public function naturalRightJoin($table)
- {
- return $this->joinInternal('natural right join', $table);
- }
- public function group($columns)
- {
- if(is_string($columns) && strpos($columns,'(')!==false)
- $this->_query['group']=$columns;
- else
- {
- if(!is_array($columns))
- $columns=preg_split('/\s*,\s*/',trim($columns),-1,PREG_SPLIT_NO_EMPTY);
- foreach($columns as $i=>$column)
- {
- if(is_object($column))
- $columns[$i]=(string)$column;
- elseif(strpos($column,'(')===false)
- $columns[$i]=$this->_connection->quoteColumnName($column);
- }
- $this->_query['group']=implode(', ',$columns);
- }
- return $this;
- }
- public function getGroup()
- {
- return isset($this->_query['group']) ? $this->_query['group'] : '';
- }
- public function setGroup($value)
- {
- $this->group($value);
- }
- public function having($conditions, $params=array())
- {
- $this->_query['having']=$this->processConditions($conditions);
- foreach($params as $name=>$value)
- $this->params[$name]=$value;
- return $this;
- }
- public function getHaving()
- {
- return isset($this->_query['having']) ? $this->_query['having'] : '';
- }
- public function setHaving($value)
- {
- $this->having($value);
- }
- public function order($columns)
- {
- if(is_string($columns) && strpos($columns,'(')!==false)
- $this->_query['order']=$columns;
- else
- {
- if(!is_array($columns))
- $columns=preg_split('/\s*,\s*/',trim($columns),-1,PREG_SPLIT_NO_EMPTY);
- foreach($columns as $i=>$column)
- {
- if(is_object($column))
- $columns[$i]=(string)$column;
- elseif(strpos($column,'(')===false)
- {
- if(preg_match('/^(.*?)\s+(asc|desc)$/i',$column,$matches))
- $columns[$i]=$this->_connection->quoteColumnName($matches[1]).' '.strtoupper($matches[2]);
- else
- $columns[$i]=$this->_connection->quoteColumnName($column);
- }
- }
- $this->_query['order']=implode(', ',$columns);
- }
- return $this;
- }
- public function getOrder()
- {
- return isset($this->_query['order']) ? $this->_query['order'] : '';
- }
- public function setOrder($value)
- {
- $this->order($value);
- }
- public function limit($limit, $offset=null)
- {
- $this->_query['limit']=(int)$limit;
- if($offset!==null)
- $this->offset($offset);
- return $this;
- }
- public function getLimit()
- {
- return isset($this->_query['limit']) ? $this->_query['limit'] : -1;
- }
- public function setLimit($value)
- {
- $this->limit($value);
- }
- public function offset($offset)
- {
- $this->_query['offset']=(int)$offset;
- return $this;
- }
- public function getOffset()
- {
- return isset($this->_query['offset']) ? $this->_query['offset'] : -1;
- }
- public function setOffset($value)
- {
- $this->offset($value);
- }
- public function union($sql)
- {
- if(isset($this->_query['union']) && is_string($this->_query['union']))
- $this->_query['union']=array($this->_query['union']);
- $this->_query['union'][]=$sql;
- return $this;
- }
- public function getUnion()
- {
- return isset($this->_query['union']) ? $this->_query['union'] : '';
- }
- public function setUnion($value)
- {
- $this->_query['union']=$value;
- }
- public function insert($table, $columns)
- {
- $params=array();
- $names=array();
- $placeholders=array();
- foreach($columns as $name=>$value)
- {
- $names[]=$this->_connection->quoteColumnName($name);
- if($value instanceof CDbExpression)
- {
- $placeholders[] = $value->expression;
- foreach($value->params as $n => $v)
- $params[$n] = $v;
- }
- else
- {
- $placeholders[] = ':' . $name;
- $params[':' . $name] = $value;
- }
- }
- $sql='INSERT INTO ' . $this->_connection->quoteTableName($table)
- . ' (' . implode(', ',$names) . ') VALUES ('
- . implode(', ', $placeholders) . ')';
- return $this->setText($sql)->execute($params);
- }
- public function update($table, $columns, $conditions='', $params=array())
- {
- $lines=array();
- foreach($columns as $name=>$value)
- {
- if($value instanceof CDbExpression)
- {
- $lines[]=$this->_connection->quoteColumnName($name) . '=' . $value->expression;
- foreach($value->params as $n => $v)
- $params[$n] = $v;
- }
- else
- {
- $lines[]=$this->_connection->quoteColumnName($name) . '=:' . $name;
- $params[':' . $name]=$value;
- }
- }
- $sql='UPDATE ' . $this->_connection->quoteTableName($table) . ' SET ' . implode(', ', $lines);
- if(($where=$this->processConditions($conditions))!='')
- $sql.=' WHERE '.$where;
- return $this->setText($sql)->execute($params);
- }
- public function delete($table, $conditions='', $params=array())
- {
- $sql='DELETE FROM ' . $this->_connection->quoteTableName($table);
- if(($where=$this->processConditions($conditions))!='')
- $sql.=' WHERE '.$where;
- return $this->setText($sql)->execute($params);
- }
- public function createTable($table, $columns, $options=null)
- {
- return $this->setText($this->getConnection()->getSchema()->createTable($table, $columns, $options))->execute();
- }
- public function renameTable($table, $newName)
- {
- return $this->setText($this->getConnection()->getSchema()->renameTable($table, $newName))->execute();
- }
- public function dropTable($table)
- {
- return $this->setText($this->getConnection()->getSchema()->dropTable($table))->execute();
- }
- public function truncateTable($table)
- {
- $schema=$this->getConnection()->getSchema();
- $n=$this->setText($schema->truncateTable($table))->execute();
- if(strncasecmp($this->getConnection()->getDriverName(),'sqlite',6)===0)
- $schema->resetSequence($schema->getTable($table));
- return $n;
- }
- public function addColumn($table, $column, $type)
- {
- return $this->setText($this->getConnection()->getSchema()->addColumn($table, $column, $type))->execute();
- }
- public function dropColumn($table, $column)
- {
- return $this->setText($this->getConnection()->getSchema()->dropColumn($table, $column))->execute();
- }
- public function renameColumn($table, $name, $newName)
- {
- return $this->setText($this->getConnection()->getSchema()->renameColumn($table, $name, $newName))->execute();
- }
- public function alterColumn($table, $column, $type)
- {
- return $this->setText($this->getConnection()->getSchema()->alterColumn($table, $column, $type))->execute();
- }
- public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete=null, $update=null)
- {
- return $this->setText($this->getConnection()->getSchema()->addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete, $update))->execute();
- }
- public function dropForeignKey($name, $table)
- {
- return $this->setText($this->getConnection()->getSchema()->dropForeignKey($name, $table))->execute();
- }
- public function createIndex($name, $table, $columns, $unique=false)
- {
- return $this->setText($this->getConnection()->getSchema()->createIndex($name, $table, $columns, $unique))->execute();
- }
- public function dropIndex($name, $table)
- {
- return $this->setText($this->getConnection()->getSchema()->dropIndex($name, $table))->execute();
- }
- private function processConditions($conditions)
- {
- if(!is_array($conditions))
- return $conditions;
- elseif($conditions===array())
- return '';
- $n=count($conditions);
- $operator=strtoupper($conditions[0]);
- if($operator==='OR' || $operator==='AND')
- {
- $parts=array();
- for($i=1;$i<$n;++$i)
- {
- $condition=$this->processConditions($conditions[$i]);
- if($condition!=='')
- $parts[]='('.$condition.')';
- }
- return $parts===array() ? '' : implode(' '.$operator.' ', $parts);
- }
- if(!isset($conditions[1],$conditions[2]))
- return '';
- $column=$conditions[1];
- if(strpos($column,'(')===false)
- $column=$this->_connection->quoteColumnName($column);
- $values=$conditions[2];
- if(!is_array($values))
- $values=array($values);
- if($operator==='IN' || $operator==='NOT IN')
- {
- if($values===array())
- return $operator==='IN' ? '0=1' : '';
- foreach($values as $i=>$value)
- {
- if(is_string($value))
- $values[$i]=$this->_connection->quoteValue($value);
- else
- $values[$i]=(string)$value;
- }
- return $column.' '.$operator.' ('.implode(', ',$values).')';
- }
- if($operator==='LIKE' || $operator==='NOT LIKE' || $operator==='OR LIKE' || $operator==='OR NOT LIKE')
- {
- if($values===array())
- return $operator==='LIKE' || $operator==='OR LIKE' ? '0=1' : '';
- if($operator==='LIKE' || $operator==='NOT LIKE')
- $andor=' AND ';
- else
- {
- $andor=' OR ';
- $operator=$operator==='OR LIKE' ? 'LIKE' : 'NOT LIKE';
- }
- $expressions=array();
- foreach($values as $value)
- $expressions[]=$column.' '.$operator.' '.$this->_connection->quoteValue($value);
- return implode($andor,$expressions);
- }
- throw new CDbException(Yii::t('yii', 'Unknown operator "{operator}".', array('{operator}'=>$operator)));
- }
- private function joinInternal($type, $table, $conditions='', $params=array())
- {
- if(strpos($table,'(')===false)
- {
- if(preg_match('/^(.*?)(?i:\s+as\s+|\s+)(.*)$/',$table,$matches)) // with alias
- $table=$this->_connection->quoteTableName($matches[1]).' '.$this->_connection->quoteTableName($matches[2]);
- else
- $table=$this->_connection->quoteTableName($table);
- }
- $conditions=$this->processConditions($conditions);
- if($conditions!='')
- $conditions=' ON '.$conditions;
- if(isset($this->_query['join']) && is_string($this->_query['join']))
- $this->_query['join']=array($this->_query['join']);
- $this->_query['join'][]=strtoupper($type) . ' ' . $table . $conditions;
- foreach($params as $name=>$value)
- $this->params[$name]=$value;
- return $this;
- }
- public function addPrimaryKey($name,$table,$columns)
- {
- return $this->setText($this->getConnection()->getSchema()->addPrimaryKey($name,$table,$columns))->execute();
- }
- public function dropPrimaryKey($name,$table)
- {
- return $this->setText($this->getConnection()->getSchema()->dropPrimaryKey($name,$table))->execute();
- }
- }
- class CDbColumnSchema extends CComponent
- {
- public $name;
- public $rawName;
- public $allowNull;
- public $dbType;
- public $type;
- public $defaultValue;
- public $size;
- public $precision;
- public $scale;
- public $isPrimaryKey;
- public $isForeignKey;
- public $autoIncrement=false;
- public $comment='';
- public function init($dbType, $defaultValue)
- {
- $this->dbType=$dbType;
- $this->extractType($dbType);
- $this->extractLimit($dbType);
- if($defaultValue!==null)
- $this->extractDefault($defaultValue);
- }
- protected function extractType($dbType)
- {
- if(stripos($dbType,'int')!==false && stripos($dbType,'unsigned int')===false)
- $this->type='integer';
- elseif(stripos($dbType,'bool')!==false)
- $this->type='boolean';
- elseif(preg_match('/(real|floa|doub)/i',$dbType))
- $this->type='double';
- else
- $this->type='string';
- }
- protected function extractLimit($dbType)
- {
- if(strpos($dbType,'(') && preg_match('/\((.*)\)/',$dbType,$matches))
- {
- $values=explode(',',$matches[1]);
- $this->size=$this->precision=(int)$values[0];
- if(isset($values[1]))
- $this->scale=(int)$values[1];
- }
- }
- protected function extractDefault($defaultValue)
- {
- $this->defaultValue=$this->typecast($defaultValue);
- }
- public function typecast($value)
- {
- if(gettype($value)===$this->type || $value===null || $value instanceof CDbExpression)
- return $value;
- if($value==='' && $this->allowNull)
- return $this->type==='string' ? '' : null;
- switch($this->type)
- {
- case 'string': return (string)$value;
- case 'integer': return (integer)$value;
- case 'boolean': return (boolean)$value;
- case 'double':
- default: return $value;
- }
- }
- }
- class CSqliteColumnSchema extends CDbColumnSchema
- {
- protected function extractDefault($defaultValue)
- {
- if($this->dbType==='timestamp' && $defaultValue==='CURRENT_TIMESTAMP')
- $this->defaultValue=null;
- else
- $this->defaultValue=$this->typecast(strcasecmp($defaultValue,'null') ? $defaultValue : null);
- if($this->type==='string' && $this->defaultValue!==null) // PHP 5.2.6 adds single quotes while 5.2.0 doesn't
- $this->defaultValue=trim($this->defaultValue,"'\"");
- }
- }
- abstract class CValidator extends CComponent
- {
- public static $builtInValidators=array(
- 'required'=>'CRequiredValidator',
- 'filter'=>'CFilterValidator',
- 'match'=>'CRegularExpressionValidator',
- 'email'=>'CEmailValidator',
- 'url'=>'CUrlValidator',
- 'unique'=>'CUniqueValidator',
- 'compare'=>'CCompareValidator',
- 'length'=>'CStringValidator',
- 'in'=>'CRangeValidator',
- 'numerical'=>'CNumberValidator',
- 'captcha'=>'CCaptchaValidator',
- 'type'=>'CTypeValidator',
- 'file'=>'CFileValidator',
- 'default'=>'CDefaultValueValidator',
- 'exist'=>'CExistValidator',
- 'boolean'=>'CBooleanValidator',
- 'safe'=>'CSafeValidator',
- 'unsafe'=>'CUnsafeValidator',
- 'date'=>'CDateValidator',
- );
- public $attributes;
- public $message;
- public $skipOnError=false;
- public $on;
- public $except;
- public $safe=true;
- public $enableClientValidation=true;
- abstract protected function validateAttribute($object,$attribute);
- public static function createValidator($name,$object,$attributes,$params=array())
- {
- if(is_string($attributes))
- $attributes=preg_split('/\s*,\s*/',$attributes,-1,PREG_SPLIT_NO_EMPTY);
- if(isset($params['on']))
- {
- if(is_array($params['on']))
- $on=$params['on'];
- else
- $on=preg_split('/[\s,]+/',$params['on'],-1,PREG_SPLIT_NO_EMPTY);
- }
- else
- $on=array();
- if(isset($params['except']))
- {
- if(is_array($params['except']))
- $except=$params['except'];
- else
- $except=preg_split('/[\s,]+/',$params['except'],-1,PREG_SPLIT_NO_EMPTY);
- }
- else
- $except=array();
- if(method_exists($object,$name))
- {
- $validator=new CInlineValidator;
- $validator->attributes=$attributes;
- $validator->method=$name;
- if(isset($params['clientValidate']))
- {
- $validator->clientValidate=$params['clientValidate'];
- unset($params['clientValidate']);
- }
- $validator->params=$params;
- if(isset($params['skipOnError']))
- $validator->skipOnError=$params['skipOnError'];
- }
- else
- {
- $params['attributes']=$attributes;
- if(isset(self::$builtInValidators[$name]))
- $className=Yii::import(self::$builtInValidators[$name],true);
- else
- $className=Yii::import($name,true);
- $validator=new $className;
- foreach($params as $name=>$value)
- $validator->$name=$value;
- }
- $validator->on=empty($on) ? array() : array_combine($on,$on);
- $validator->except=empty($except) ? array() : array_combine($except,$except);
- return $validator;
- }
- public function validate($object,$attributes=null)
- {
- if(is_array($attributes))
- $attributes=array_intersect($this->attributes,$attributes);
- else
- $attributes=$this->attributes;
- foreach($attributes as $attribute)
- {
- if(!$this->skipOnError || !$object->hasErrors($attribute))
- $this->validateAttribute($object,$attribute);
- }
- }
- public function clientValidateAttribute($object,$attribute)
- {
- }
- public function applyTo($scenario)
- {
- if(isset($this->except[$scenario]))
- return false;
- return empty($this->on) || isset($this->on[$scenario]);
- }
- protected function addError($object,$attribute,$message,$params=array())
- {
- $params['{attribute}']=$object->getAttributeLabel($attribute);
- $object->addError($attribute,strtr($message,$params));
- }
- protected function isEmpty($value,$trim=false)
- {
- return $value===null || $value===array() || $value==='' || $trim && is_scalar($value) && trim($value)==='';
- }
- }
- class CStringValidator extends CValidator
- {
- public $max;
- public $min;
- public $is;
- public $tooShort;
- public $tooLong;
- public $allowEmpty=true;
- public $encoding;
- protected function validateAttribute($object,$attribute)
- {
- $value=$object->$attribute;
- if($this->allowEmpty && $this->isEmpty($value))
- return;
- if(is_array($value))
- {
- // https://github.com/yiisoft/yii/issues/1955
- $this->addError($object,$attribute,Yii::t('yii','{attribute} is invalid.'));
- return;
- }
- if(function_exists('mb_strlen') && $this->encoding!==false)
- $length=mb_strlen($value, $this->encoding ? $this->encoding : Yii::app()->charset);
- else
- $length=strlen($value);
- if($this->min!==null && $length<$this->min)
- {
- $message=$this->tooShort!==null?$this->tooShort:Yii::t('yii','{attribute} is too short (minimum is {min} characters).');
- $this->addError($object,$attribute,$message,array('{min}'=>$this->min));
- }
- if($this->max!==null && $length>$this->max)
- {
- $message=$this->tooLong!==null?$this->tooLong:Yii::t('yii','{attribute} is too long (maximum is {max} characters).');
- $this->addError($object,$attribute,$message,array('{max}'=>$this->max));
- }
- if($this->is!==null && $length!==$this->is)
- {
- $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} is of the wrong length (should be {length} characters).');
- $this->addError($object,$attribute,$message,array('{length}'=>$this->is));
- }
- }
- public function clientValidateAttribute($object,$attribute)
- {
- $label=$object->getAttributeLabel($attribute);
- if(($message=$this->message)===null)
- $message=Yii::t('yii','{attribute} is of the wrong length (should be {length} characters).');
- $message=strtr($message, array(
- '{attribute}'=>$label,
- '{length}'=>$this->is,
- ));
- if(($tooShort=$this->tooShort)===null)
- $tooShort=Yii::t('yii','{attribute} is too short (minimum is {min} characters).');
- $tooShort=strtr($tooShort, array(
- '{attribute}'=>$label,
- '{min}'=>$this->min,
- ));
- if(($tooLong=$this->tooLong)===null)
- $tooLong=Yii::t('yii','{attribute} is too long (maximum is {max} characters).');
- $tooLong=strtr($tooLong, array(
- '{attribute}'=>$label,
- '{max}'=>$this->max,
- ));
- $js='';
- if($this->min!==null)
- {
- $js.="
- if(value.length<{$this->min}) {
- messages.push(".CJSON::encode($tooShort).");
- }
- ";
- }
- if($this->max!==null)
- {
- $js.="
- if(value.length>{$this->max}) {
- messages.push(".CJSON::encode($tooLong).");
- }
- ";
- }
- if($this->is!==null)
- {
- $js.="
- if(value.length!={$this->is}) {
- messages.push(".CJSON::encode($message).");
- }
- ";
- }
- if($this->allowEmpty)
- {
- $js="
- if(jQuery.trim(value)!='') {
- $js
- }
- ";
- }
- return $js;
- }
- }
- class CRequiredValidator extends CValidator
- {
- public $requiredValue;
- public $strict=false;
- public $trim=true;
- protected function validateAttribute($object,$attribute)
- {
- $value=$object->$attribute;
- if($this->requiredValue!==null)
- {
- if(!$this->strict && $value!=$this->requiredValue || $this->strict && $value!==$this->requiredValue)
- {
- $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be {value}.',
- array('{value}'=>$this->requiredValue));
- $this->addError($object,$attribute,$message);
- }
- }
- elseif($this->isEmpty($value,$this->trim))
- {
- $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} cannot be blank.');
- $this->addError($object,$attribute,$message);
- }
- }
- public function clientValidateAttribute($object,$attribute)
- {
- $message=$this->message;
- if($this->requiredValue!==null)
- {
- if($message===null)
- $message=Yii::t('yii','{attribute} must be {value}.');
- $message=strtr($message, array(
- '{value}'=>$this->requiredValue,
- '{attribute}'=>$object->getAttributeLabel($attribute),
- ));
- return "
- if(value!=" . CJSON::encode($this->requiredValue) . ") {
- messages.push(".CJSON::encode($message).");
- }
- ";
- }
- else
- {
- if($message===null)
- $message=Yii::t('yii','{attribute} cannot be blank.');
- $message=strtr($message, array(
- '{attribute}'=>$object->getAttributeLabel($attribute),
- ));
- if($this->trim)
- $emptyCondition = "jQuery.trim(value)==''";
- else
- $emptyCondition = "value==''";
- return "
- if({$emptyCondition}) {
- messages.push(".CJSON::encode($message).");
- }
- ";
- }
- }
- }
- class CNumberValidator extends CValidator
- {
- public $integerOnly=false;
- public $allowEmpty=true;
- public $max;
- public $min;
- public $tooBig;
- public $tooSmall;
- public $integerPattern='/^\s*[+-]?\d+\s*$/';
- public $numberPattern='/^\s*[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\s*$/';
- protected function validateAttribute($object,$attribute)
- {
- $value=$object->$attribute;
- if($this->allowEmpty && $this->isEmpty($value))
- return;
- if(!is_numeric($value))
- {
- // https://github.com/yiisoft/yii/issues/1955
- // https://github.com/yiisoft/yii/issues/1669
- $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be a number.');
- $this->addError($object,$attribute,$message);
- return;
- }
- if($this->integerOnly)
- {
- if(!preg_match($this->integerPattern,"$value"))
- {
- $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be an integer.');
- $this->addError($object,$attribute,$message);
- }
- }
- else
- {
- if(!preg_match($this->numberPattern,"$value"))
- {
- $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be a number.');
- $this->addError($object,$attribute,$message);
- }
- }
- if($this->min!==null && $value<$this->min)
- {
- $message=$this->tooSmall!==null?$this->tooSmall:Yii::t('yii','{attribute} is too small (minimum is {min}).');
- $this->addError($object,$attribute,$message,array('{min}'=>$this->min));
- }
- if($this->max!==null && $value>$this->max)
- {
- $message=$this->tooBig!==null?$this->tooBig:Yii::t('yii','{attribute} is too big (maximum is {max}).');
- $this->addError($object,$attribute,$message,array('{max}'=>$this->max));
- }
- }
- public function clientValidateAttribute($object,$attribute)
- {
- $label=$object->getAttributeLabel($attribute);
- if(($message=$this->message)===null)
- $message=$this->integerOnly ? Yii::t('yii','{attribute} must be an integer.') : Yii::t('yii','{attribute} must be a number.');
- $message=strtr($message, array(
- '{attribute}'=>$label,
- ));
- if(($tooBig=$this->tooBig)===null)
- $tooBig=Yii::t('yii','{attribute} is too big (maximum is {max}).');
- $tooBig=strtr($tooBig, array(
- '{attribute}'=>$label,
- '{max}'=>$this->max,
- ));
- if(($tooSmall=$this->tooSmall)===null)
- $tooSmall=Yii::t('yii','{attribute} is too small (minimum is {min}).');
- $tooSmall=strtr($tooSmall, array(
- '{attribute}'=>$label,
- '{min}'=>$this->min,
- ));
- $pattern=$this->integerOnly ? $this->integerPattern : $this->numberPattern;
- $js="
- if(!value.match($pattern)) {
- messages.push(".CJSON::encode($message).");
- }
- ";
- if($this->min!==null)
- {
- $js.="
- if(value<{$this->min}) {
- messages.push(".CJSON::encode($tooSmall).");
- }
- ";
- }
- if($this->max!==null)
- {
- $js.="
- if(value>{$this->max}) {
- messages.push(".CJSON::encode($tooBig).");
- }
- ";
- }
- if($this->allowEmpty)
- {
- $js="
- if(jQuery.trim(value)!='') {
- $js
- }
- ";
- }
- return $js;
- }
- }
- class CListIterator implements Iterator
- {
- private $_d;
- private $_i;
- private $_c;
- public function __construct(&$data)
- {
- $this->_d=&$data;
- $this->_i=0;
- $this->_c=count($this->_d);
- }
- public function rewind()
- {
- $this->_i=0;
- }
- public function key()
- {
- return $this->_i;
- }
- public function current()
- {
- return $this->_d[$this->_i];
- }
- public function next()
- {
- $this->_i++;
- }
- public function valid()
- {
- return $this->_i<$this->_c;
- }
- }
- interface IApplicationComponent
- {
- public function init();
- public function getIsInitialized();
- }
- interface ICache
- {
- public function get($id);
- public function mget($ids);
- public function set($id,$value,$expire=0,$dependency=null);
- public function add($id,$value,$expire=0,$dependency=null);
- public function delete($id);
- public function flush();
- }
- interface ICacheDependency
- {
- public function evaluateDependency();
- public function getHasChanged();
- }
- interface IStatePersister
- {
- public function load();
- public function save($state);
- }
- interface IFilter
- {
- public function filter($filterChain);
- }
- interface IAction
- {
- public function getId();
- public function getController();
- }
- interface IWebServiceProvider
- {
- public function beforeWebMethod($service);
- public function afterWebMethod($service);
- }
- interface IViewRenderer
- {
- public function renderFile($context,$file,$data,$return);
- }
- interface IUserIdentity
- {
- public function authenticate();
- public function getIsAuthenticated();
- public function getId();
- public function getName();
- public function getPersistentStates();
- }
- interface IWebUser
- {
- public function getId();
- public function getName();
- public function getIsGuest();
- public function checkAccess($operation,$params=array());
- public function loginRequired();
- }
- interface IAuthManager
- {
- public function checkAccess($itemName,$userId,$params=array());
- public function createAuthItem($name,$type,$description='',$bizRule=null,$data=null);
- public function removeAuthItem($name);
- public function getAuthItems($type=null,$userId=null);
- public function getAuthItem($name);
- public function saveAuthItem($item,$oldName=null);
- public function addItemChild($itemName,$childName);
- public function removeItemChild($itemName,$childName);
- public function hasItemChild($itemName,$childName);
- public function getItemChildren($itemName);
- public function assign($itemName,$userId,$bizRule=null,$data=null);
- public function revoke($itemName,$userId);
- public function isAssigned($itemName,$userId);
- public function getAuthAssignment($itemName,$userId);
- public function getAuthAssignments($userId);
- public function saveAuthAssignment($assignment);
- public function clearAll();
- public function clearAuthAssignments();
- public function save();
- public function executeBizRule($bizRule,$params,$data);
- }
- interface IBehavior
- {
- public function attach($component);
- public function detach($component);
- public function getEnabled();
- public function setEnabled($value);
- }
- interface IWidgetFactory
- {
- public function createWidget($owner,$className,$properties=array());
- }
- interface IDataProvider
- {
- public function getId();
- public function getItemCount($refresh=false);
- public function getTotalItemCount($refresh=false);
- public function getData($refresh=false);
- public function getKeys($refresh=false);
- public function getSort();
- public function getPagination();
- }
- interface ILogFilter
- {
- public function filter(&$logs);
- }
- ?>
|