api.workaround.php 312 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012
  1. <?php
  2. /**
  3. * Returns typical back to profile/editing controls
  4. *
  5. * @param string $login
  6. * @return string
  7. */
  8. function web_UserControls($login) {
  9. global $ubillingConfig;
  10. $oldStyleFlag = $ubillingConfig->getAlterParam('OLD_USERCONTROLS');
  11. $urlProfile = '?module=userprofile&username=';
  12. $urlUserEdit = '?module=useredit&username=';
  13. $controls = wf_tag('div', false);
  14. if ($oldStyleFlag) {
  15. $controls .= wf_Link($urlProfile . $login, wf_img_sized('skins/icon_user_big.gif', __('Back to user profile'), '48') . __('Back to user profile'), true, '');
  16. $controls .= wf_tag('br');
  17. $controls .= wf_Link($urlUserEdit . $login, wf_img_sized('skins/icon_user_edit_big.gif', __('Back to user edit'), '48') . __('Back to user edit'), false, '');
  18. } else {
  19. if (cfr('USERPROFILE')) {
  20. $controls .= wf_Link($urlProfile . $login, wf_img_sized('skins/backprofile.png', __('Back to user profile'), '16') . ' ' . __('Back to user profile'), false, 'ubbackprofile') . ' ';
  21. }
  22. if ((cfr('USEREDIT')) and (@$_GET['module'] != 'useredit')) {
  23. $controls .= wf_Link($urlUserEdit . $login, wf_img_sized('skins/backedit.png', __('Back to user edit'), '16') . ' ' . __('Back to user edit'), false, 'ubbackedit');
  24. }
  25. }
  26. $controls .= wf_tag('div', true);
  27. return ($controls);
  28. }
  29. /**
  30. * return current locale in two letter format
  31. *
  32. * @return string
  33. */
  34. function curlang() {
  35. global $system;
  36. $result = $system->language;
  37. $result = vf($result);
  38. return ($result);
  39. }
  40. /**
  41. * Returns user logins with non unique passwords
  42. *
  43. * @return array
  44. */
  45. function zb_GetNonUniquePasswordUsers() {
  46. $query_p = "SELECT `Password`,count(*) as cnt from `users` GROUP BY `Password` having cnt >1;";
  47. $duppasswords = simple_queryall($query_p);
  48. $result = array();
  49. if (!empty($duppasswords)) {
  50. foreach ($duppasswords as $io => $each) {
  51. $query_l = "SELECT `login` from `users` WHERE `Password`='" . $each['Password'] . "'";
  52. $userlogins = simple_queryall($query_l);
  53. if (!empty($userlogins)) {
  54. foreach ($userlogins as $ia => $eachlogin) {
  55. $result[] = $eachlogin['login'];
  56. }
  57. }
  58. }
  59. }
  60. return ($result);
  61. }
  62. /**
  63. * Checks is some password unique
  64. *
  65. * @param string $password
  66. * @return bool
  67. */
  68. function zb_CheckPasswordUnique($password) {
  69. $password = mysql_real_escape_string($password);
  70. $query = "SELECT `login` from `users` WHERE `Password`='" . $password . "'";
  71. $data = simple_query($query);
  72. if (empty($data)) {
  73. return (true);
  74. } else {
  75. return (false);
  76. }
  77. }
  78. /**
  79. * Returns localised calendar control. Used only for backward compat with old modules.
  80. * Use wf_DatePicker() instead.
  81. *
  82. * @param string $field
  83. * @return string
  84. */
  85. function web_CalendarControl($field) {
  86. $result = wf_DatePicker($field);
  87. return ($result);
  88. }
  89. /**
  90. * Returns localised boolean value in human-readable view
  91. *
  92. * @param bool $value
  93. * @return string
  94. */
  95. function web_trigger($value) {
  96. if ($value) {
  97. $result = __('Yes');
  98. } else {
  99. $result = __('No');
  100. }
  101. return ($result);
  102. }
  103. /**
  104. * Returns form for editing one field string data
  105. *
  106. * @param array $fieldnames
  107. * @param string $fieldkey
  108. * @param string $useraddress
  109. * @param string $olddata
  110. * @param string $pattern
  111. *
  112. * @return string
  113. */
  114. function web_EditorStringDataForm($fieldnames, $fieldkey, $useraddress, $olddata = '', $pattern = '') {
  115. $field1 = $fieldnames['fieldname1'];
  116. $field2 = $fieldnames['fieldname2'];
  117. $cells = wf_TableCell(__('User'), '', 'row2');
  118. $cells .= wf_TableCell($useraddress, '', 'row3');
  119. $rows = wf_TableRow($cells);
  120. $cells = wf_TableCell($field1, '', 'row2');
  121. $cells .= wf_TableCell($olddata, '', 'row3');
  122. $rows .= wf_TableRow($cells);
  123. $cells = wf_TableCell($field2, '', 'row2');
  124. $cells .= wf_TableCell(wf_TextInput($fieldkey, '', '', false, '', $pattern), '', 'row3');
  125. $rows .= wf_TableRow($cells);
  126. $form = wf_TableBody($rows, '100%', 0);
  127. $form .= wf_Submit(__('Change'));
  128. $form = wf_Form("", 'POST', $form, '');
  129. $form .= wf_delimiter();
  130. return ($form);
  131. }
  132. /**
  133. * Returns suspect cash JS alert
  134. *
  135. * @param float $suspect
  136. * @return string
  137. */
  138. function js_CashCheck($suspect) {
  139. $suspect = vf($suspect, 3);
  140. $result = '
  141. <script type="text/javascript">
  142. function cashsuspectalert() {
  143. alert(\'' . __('You try to bring to account suspiciously large amount of money. We have nothing against, but please check that all is correct') . '\');
  144. }
  145. function checkcashfield()
  146. {
  147. var cashfield=document.getElementById("cashfield").value;
  148. if (cashfield > ' . $suspect . ') {
  149. cashsuspectalert();
  150. }
  151. }
  152. </script>
  153. ';
  154. return ($result);
  155. }
  156. /**
  157. * Returns form for editing one field string password data
  158. *
  159. * @param array $fieldnames
  160. * @param string $fieldkey
  161. * @param string $useraddress
  162. * @param string $olddata
  163. * @return string
  164. */
  165. function web_EditorStringDataFormPassword($fieldnames, $fieldkey, $useraddress, $olddata = '') {
  166. global $ubillingConfig;
  167. $field1 = $fieldnames['fieldname1'];
  168. $field2 = $fieldnames['fieldname2'];
  169. $alterconf = $ubillingConfig->getAlter();
  170. $passwordsType = (isset($alterconf['PASSWORD_TYPE'])) ? $alterconf['PASSWORD_TYPE'] : 1;
  171. $passwordsLenght = (isset($alterconf['PASSWORD_GENERATION_LENGHT'])) ? $alterconf['PASSWORD_GENERATION_LENGHT'] : 8;
  172. $password_proposal = '';
  173. switch ($passwordsType) {
  174. case 0:
  175. $password_proposal = zb_rand_digits($passwordsLenght);
  176. break;
  177. case 1:
  178. $password_proposal = zb_rand_string($passwordsLenght);
  179. break;
  180. case 2:
  181. $password_proposal = zb_PasswordGenerate($passwordsLenght);
  182. break;
  183. case 3:
  184. $password_proposal = zb_PasswordGenerateTH($passwordsLenght);
  185. break;
  186. default:
  187. $password_proposal = zb_rand_string(8);
  188. break;
  189. }
  190. $cells = wf_TableCell(__('User'), '', 'row2');
  191. $cells .= wf_TableCell($useraddress, '', 'row3');
  192. $rows = wf_TableRow($cells);
  193. $cells = wf_TableCell($field1, '', 'row2');
  194. $cells .= wf_TableCell($olddata, '', 'row3');
  195. $rows .= wf_TableRow($cells);
  196. $cells = wf_TableCell($field2, '', 'row2');
  197. $cells .= wf_TableCell(wf_TextInput($fieldkey, '', $password_proposal, false, ''), '', 'row3');
  198. $rows .= wf_TableRow($cells);
  199. $form = wf_TableBody($rows, '100%', 0);
  200. $form .= wf_Submit(__('Change'));
  201. $form = wf_Form("", 'POST', $form, '');
  202. $form .= wf_delimiter();
  203. return ($form);
  204. }
  205. /**
  206. * Returns form for editing one field string contract data
  207. *
  208. * @param array $fieldnames
  209. * @param string $fieldkey
  210. * @param string $useraddress
  211. * @param string $olddata
  212. * @return string
  213. */
  214. function web_EditorStringDataFormContract($fieldnames, $fieldkey, $useraddress, $olddata = '') {
  215. $altcfg = rcms_parse_ini_file(CONFIG_PATH . "alter.ini");
  216. $field1 = $fieldnames['fieldname1'];
  217. $field2 = $fieldnames['fieldname2'];
  218. $olddata = trim($olddata);
  219. if (empty($olddata)) {
  220. $allcontracts = zb_UserGetAllContracts();
  221. $top_offset = 100000;
  222. //contract generation mode default
  223. if ($altcfg['CONTRACT_GENERATION_DEFAULT']) {
  224. for ($i = 1; $i < $top_offset; $i++) {
  225. if (!isset($allcontracts[$i])) {
  226. $contract_proposal = $i;
  227. break;
  228. }
  229. }
  230. } else {
  231. //alternate generation method
  232. $max_contract = max(array_keys($allcontracts));
  233. $contract_proposal = $max_contract + 1;
  234. }
  235. } else {
  236. $contract_proposal = '';
  237. }
  238. $cells = wf_TableCell(__('User'), '', 'row2');
  239. $cells .= wf_TableCell($useraddress, '', 'row3');
  240. $rows = wf_TableRow($cells);
  241. $cells = wf_TableCell($field1, '', 'row2');
  242. $cells .= wf_TableCell($olddata, '', 'row3');
  243. $rows .= wf_TableRow($cells);
  244. $cells = wf_TableCell($field2, '', 'row2');
  245. $cells .= wf_TableCell(wf_TextInput($fieldkey, '', $contract_proposal, false, ''), '', 'row3');
  246. $rows .= wf_TableRow($cells);
  247. $table = wf_TableBody($rows, '100%', 0);
  248. $inputs = $table;
  249. $inputs .= wf_Submit(__('Change'));
  250. $inputs .= wf_delimiter();
  251. $form = wf_Form("", 'POST', $inputs, '');
  252. return ($form);
  253. }
  254. /**
  255. * Returns simple MAC address selector
  256. *
  257. * @global object $ubillingConfig
  258. * @param string $name
  259. * @return string
  260. */
  261. function zb_NewMacSelect($name = 'newmac') {
  262. global $ubillingConfig;
  263. $allUsedMacs = zb_getAllUsedMac();
  264. $allMacs = array();
  265. $resultArr = array();
  266. $lineLimit = ($ubillingConfig->getAlterParam('NMLOOKUP_DEPTH')) ? $ubillingConfig->getAlterParam('NMLOOKUP_DEPTH') : 200;
  267. $leases = $ubillingConfig->getAlterParam('NMLEASES');
  268. $additionalSources = $ubillingConfig->getAlterParam('NMSOURCES_ADDITIONAL');
  269. $reverseFlag = ($ubillingConfig->getAlterParam('NMREVERSE')) ? true : false;
  270. $searchableFlag = ($ubillingConfig->getAlterParam('MACSEL_SEARCHBL')) ? true : false;
  271. $additionalMark = ($ubillingConfig->getAlterParam('NMLEASEMARK_ADDITIONAL')) ? $ubillingConfig->getAlterParam('NMLEASEMARK_ADDITIONAL') : '';
  272. //parsing new MAC sources
  273. if (!empty($leases)) {
  274. $allMacs += zb_MacParseSource($leases, $lineLimit);
  275. }
  276. //and optional supplementary sources
  277. if (!empty($additionalSources)) {
  278. $additionalSources = explode(',', $additionalSources);
  279. if (!empty($additionalSources)) {
  280. foreach ($additionalSources as $io => $eachAdditionalSource) {
  281. $supSourceMacs = zb_MacParseSource($eachAdditionalSource, $lineLimit, $additionalMark);
  282. $allMacs = array_merge($allMacs, $supSourceMacs);
  283. }
  284. }
  285. }
  286. if (!empty($allMacs)) {
  287. foreach ($allMacs as $io => $newmac) {
  288. if (zb_checkMacFree($newmac, $allUsedMacs)) {
  289. $resultArr[$newmac] = $newmac;
  290. }
  291. }
  292. //revert array due usability reasons (i hope).
  293. if ($reverseFlag) {
  294. $resultArr = array_reverse($resultArr);
  295. }
  296. }
  297. //searchable MAC selector?
  298. if ($searchableFlag) {
  299. $result = wf_SelectorSearchable($name, $resultArr, '', '', false);
  300. } else {
  301. $result = wf_Selector($name, $resultArr, '', '', false);
  302. }
  303. return ($result);
  304. }
  305. /**
  306. * Renders user MAC editing form
  307. *
  308. * @global object $ubillingConfig
  309. * @param string $userAddress
  310. * @param bool $manualInput
  311. * @param string $currentMac
  312. *
  313. * @return string
  314. */
  315. function web_MacEditForm($userAddress = '', $manualInput = false, $currentMac = '') {
  316. global $ubillingConfig;
  317. $altCfg = $ubillingConfig->getAlter();
  318. $lookuplink = '';
  319. $newValue = '';
  320. $result = '';
  321. //mac vendor search
  322. if ($altCfg['MACVEN_ENABLED']) {
  323. if (cfr('MACVEN')) {
  324. $optionState = $altCfg['MACVEN_ENABLED'];
  325. switch ($optionState) {
  326. case 1:
  327. $lookupUrl = '?module=macvendor&modalpopup=true&mac=' . $currentMac . '&username=';
  328. $lookuplink = wf_AjaxLink($lookupUrl, wf_img('skins/macven.gif', __('Device vendor')), 'macvendorcontainer', false);
  329. $lookuplink .= wf_AjaxContainerSpan('macvendorcontainer', '', '');
  330. break;
  331. case 2:
  332. $vendorframe = wf_tag('iframe', false, '', 'src="?module=macvendor&mac=' . $currentMac . '" width="360" height="160" frameborder="0"');
  333. $vendorframe .= wf_tag('iframe', true);
  334. $lookuplink = wf_modalAuto(wf_img('skins/macven.gif', __('Device vendor')), __('Device vendor'), $vendorframe, '');
  335. break;
  336. case 3:
  337. $lookupUrl = '?module=macvendor&raw=true&mac=' . $currentMac;
  338. $lookuplink = wf_AjaxLink($lookupUrl, wf_img('skins/macven.gif', __('Device vendor')), 'macvendorcontainer', false);
  339. $lookuplink .= wf_AjaxContainerSpan('macvendorcontainer', '', '');
  340. break;
  341. }
  342. }
  343. }
  344. //only for manual input form
  345. if ($manualInput) {
  346. //random MAC preset
  347. if ($altCfg['MACCHANGERANDOMDEFAULT']) {
  348. $randomMac = zb_MacGetRandom();
  349. if (zb_mac_unique($randomMac)) {
  350. $newValue = $randomMac;
  351. } else {
  352. show_error('Oops');
  353. $newValue = '';
  354. }
  355. }
  356. }
  357. //custom input types here
  358. if ($manualInput) {
  359. $macInput = wf_TextInput('newmac', '', $newValue, false, '', 'mac');
  360. } else {
  361. $macInput = zb_NewMacSelect();
  362. }
  363. $cells = wf_TableCell(__('User'), '', 'row2');
  364. $cells .= wf_TableCell($userAddress, '', 'row3');
  365. $rows = wf_TableRow($cells);
  366. $cells = wf_TableCell(__('Current MAC') . ' ' . $lookuplink, '', 'row2');
  367. $cells .= wf_TableCell($currentMac, '', 'row3');
  368. $rows .= wf_TableRow($cells);
  369. $cells = wf_TableCell(__('New MAC'), '', 'row2');
  370. $cells .= wf_TableCell($macInput, '', 'row3');
  371. $rows .= wf_TableRow($cells);
  372. $table = wf_TableBody($rows, '100%', 0);
  373. $inputs = $table;
  374. $inputs .= wf_Submit(__('Change'));
  375. $inputs .= wf_delimiter();
  376. $result .= wf_Form('', 'POST', $inputs, '');
  377. return ($result);
  378. }
  379. /**
  380. * Credit expire date editor
  381. *
  382. * @param array $fieldnames
  383. * @param string $fieldkey
  384. * @param string $useraddress
  385. * @param string $olddata
  386. * @return string
  387. */
  388. function web_EditorDateDataForm($fieldnames, $fieldkey, $useraddress, $olddata = '') {
  389. $field1 = $fieldnames['fieldname1'];
  390. $field2 = $fieldnames['fieldname2'];
  391. $cells = wf_TableCell(__('User'), '', 'row2');
  392. $cells .= wf_TableCell($useraddress, '', 'row3');
  393. $rows = wf_TableRow($cells);
  394. $cells = wf_TableCell($field1, '', 'row2');
  395. $cells .= wf_TableCell($olddata, '', 'row3');
  396. $rows .= wf_TableRow($cells);
  397. $cells = wf_TableCell($field2, '', 'row2');
  398. $cells .= wf_TableCell(wf_DatePicker($fieldkey, false), '', 'row3');
  399. $rows .= wf_TableRow($cells);
  400. $table = wf_TableBody($rows, '100%', 0);
  401. $inputs = $table;
  402. $inputs .= wf_Submit(__('Change'));
  403. $inputs .= wf_delimiter();
  404. $form = wf_Form("", 'POST', $inputs, '');
  405. return ($form);
  406. }
  407. /**
  408. * Returns cash type selector for manual payments
  409. *
  410. * @return string
  411. */
  412. function web_CashTypeSelector($CashType = '') {
  413. $allcashtypes = zb_CashGetAlltypes();
  414. $cashtypes = array();
  415. if (!empty($allcashtypes)) {
  416. foreach ($allcashtypes as $io => $each) {
  417. $cashtypes[$each['id']] = __($each['cashtype']);
  418. }
  419. $defaultCashtype = zb_StorageGet('DEF_CT');
  420. //if no default cashtype selected
  421. if (empty($defaultCashtype)) {
  422. $defaultCashtype = 'NOP';
  423. }
  424. $selectCashType = (!empty($CashType)) ? $CashType : $defaultCashtype;
  425. $selector = wf_Selector('cashtype', $cashtypes, '', $selectCashType, false);
  426. }
  427. return ($selector);
  428. }
  429. /**
  430. * Checks is table with some name exists, and returns int value 0/1 used as bool (Oo)
  431. *
  432. * @param string $tablename
  433. * @return int
  434. */
  435. function zb_CheckTableExists($tablename) {
  436. $query = "SELECT CASE WHEN (SELECT COUNT(*) AS STATUS FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = (SELECT DATABASE()) AND TABLE_NAME = '" . $tablename . "') = 1 THEN (SELECT 1) ELSE (SELECT 0) END AS result;";
  437. $result = simple_query($query);
  438. return ($result['result']);
  439. }
  440. /**
  441. * Returns primary cash management form
  442. *
  443. * @global object $ubillingConfig
  444. * @param array $fieldnames
  445. * @param string $fieldkey
  446. * @param string $useraddress
  447. * @param string $olddata
  448. * @param float $tariff_price
  449. * @return string
  450. */
  451. function web_EditorCashDataForm($fieldnames, $fieldkey, $useraddress, $olddata = '', $tariff_price = '', $userrealname = '') {
  452. global $ubillingConfig;
  453. $field1 = $fieldnames['fieldname1'];
  454. $field2 = $fieldnames['fieldname2'];
  455. $me = whoami();
  456. //cash suspect checking
  457. $alterconf = $ubillingConfig->getAlter();
  458. //balance editing limiting
  459. $limitedFinance = false;
  460. if (@$alterconf['CAN_TOUCH_MONEY']) {
  461. if (!empty($alterconf['CAN_TOUCH_MONEY'])) {
  462. $limitedFinance = true;
  463. $godministrators = explode(',', $alterconf['CAN_TOUCH_MONEY']); //coma separated
  464. $godministrators = array_flip($godministrators);
  465. }
  466. }
  467. if ($alterconf['SUSP_PAYMENTS_NOTIFY']) {
  468. $suspnotifyscript = js_CashCheck($alterconf['SUSP_PAYMENTS_NOTIFY']);
  469. $cashfieldanchor = 'onchange="checkcashfield();"';
  470. } else {
  471. $suspnotifyscript = '';
  472. $cashfieldanchor = '';
  473. }
  474. if ($alterconf['SETCASH_ONLY_ROOT']) {
  475. if (cfr('ROOT')) {
  476. $setCashControl = wf_RadioInput('operation', __('Set cash'), 'set', false, false);
  477. } else {
  478. $setCashControl = '';
  479. }
  480. } else {
  481. $setCashControl = wf_RadioInput('operation', __('Set cash'), 'set', false, false);
  482. }
  483. $radio = '';
  484. $radio .= wf_RadioInput('operation', __('Add cash'), 'add', false, true);
  485. //additional controls
  486. $extRadio = '';
  487. $extRadio .= wf_RadioInput('operation', __('Correct saldo'), 'correct', false, false);
  488. $extRadio .= wf_RadioInput('operation', __('Mock payment'), 'mock', false, false);
  489. $extRadio .= $setCashControl;
  490. if ($limitedFinance) {
  491. if (isset($godministrators[$me])) {
  492. $radio .= $extRadio;
  493. }
  494. } else {
  495. $radio .= $extRadio;
  496. }
  497. //cash input widget
  498. $cashInputControl = wf_tag('input', false, '', ' type="text" name="' . $fieldkey . '" size="5" id="cashfield" ' . $cashfieldanchor . ' autofocus');
  499. $cashInputControl .= ' ' . __('The expected payment') . ': ' . $tariff_price;
  500. $cells = wf_TableCell(__('User'), '', 'row2');
  501. $cells .= wf_TableCell($useraddress, '', 'row3');
  502. $rows = wf_TableRow($cells);
  503. if (!empty($userrealname)) {
  504. $cells = wf_TableCell('', '', 'row2');
  505. $cells .= wf_TableCell($userrealname, '', 'row3');
  506. $rows .= wf_TableRow($cells);
  507. }
  508. $cells = wf_TableCell($field1, '', 'row2');
  509. $cells .= wf_TableCell(wf_tag('b') . $olddata . wf_tag('b', true), '', 'row3');
  510. $rows .= wf_TableRow($cells);
  511. $cells = wf_TableCell($field2, '', 'row2');
  512. $cells .= wf_TableCell($cashInputControl, '', 'row3');
  513. $rows .= wf_TableRow($cells);
  514. $cells = wf_TableCell(__('Actions'), '', 'row2');
  515. $cells .= wf_TableCell($radio, '', 'row3');
  516. $rows .= wf_TableRow($cells);
  517. $cells = wf_TableCell(__('Payment type'), '', 'row2');
  518. $cells .= wf_TableCell(web_CashTypeSelector(), '', 'row3');
  519. $rows .= wf_TableRow($cells);
  520. $cells = wf_TableCell(__('Payment notes'), '', 'row2');
  521. $cells .= wf_TableCell(wf_TextInput('newpaymentnote', '', '', false, 40), '', 'row3');
  522. $rows .= wf_TableRow($cells);
  523. $table = wf_TableBody($rows, '100%', 0, '');
  524. if ($ubillingConfig->getAlterParam('DREAMKAS_ENABLED')) {
  525. $DreamKas = new DreamKas();
  526. $table .= $DreamKas->web_FiscalizePaymentCtrls('internet');
  527. $table .= wf_tag('script', false, '', 'type="text/javascript"');
  528. $table .= '$(document).ready(function() {
  529. // dirty hack with setTimeout() to work in Chrome
  530. setTimeout(function(){
  531. $(\'#cashfield\').focus();
  532. }, 100);
  533. });
  534. ';
  535. $table .= wf_tag('script', true);
  536. }
  537. $table .= wf_Submit(__('Payment'));
  538. $form = $suspnotifyscript;
  539. $form .= wf_Form('', 'POST', $table, '');
  540. $form .= wf_delimiter();
  541. return ($form);
  542. }
  543. /**
  544. * Returns 0/1 trigger selector
  545. *
  546. * @param string $name
  547. * @param int $state
  548. * @param bool $disableYes
  549. *
  550. * @return string
  551. */
  552. function web_TriggerSelector($name, $state = '', $disableYes = false) {
  553. $noflag = (!$state) ? 'SELECTED' : '';
  554. $disableYes = ($disableYes) ? ' disabled ' : '';
  555. $selector = wf_tag('select', false, '', 'name="' . $name . '"');
  556. $selector .= wf_tag('option', false, '', 'value="1"' . $disableYes) . __('Yes') . wf_tag('option', true);
  557. $selector .= wf_tag('option', false, '', 'value="0" ' . $noflag) . __('No') . wf_tag('option', true);
  558. $selector .= wf_tag('select', true);
  559. return ($selector);
  560. }
  561. /**
  562. * Returns string editor grid edit form
  563. *
  564. * @param string $fieldname
  565. * @param string $fieldkey
  566. * @param string $useraddress
  567. * @param string $olddata
  568. * @param bool $disableYes
  569. *
  570. * @return string
  571. */
  572. function web_EditorTrigerDataForm($fieldname, $fieldkey, $useraddress, $olddata = '', $disableYes = false) {
  573. $curstate = web_trigger($olddata);
  574. $cells = wf_TableCell(__('User'), '', 'row2');
  575. $cells .= wf_TableCell($useraddress, '', 'row3');
  576. $rows = wf_TableRow($cells);
  577. $cells = wf_TableCell($fieldname, '', 'row2');
  578. $cells .= wf_TableCell($curstate, '', 'row3');
  579. $rows .= wf_TableRow($cells);
  580. $cells = wf_TableCell('', '', 'row2');
  581. $cells .= wf_TableCell(web_TriggerSelector($fieldkey, $olddata, $disableYes), '', 'row3');
  582. $rows .= wf_TableRow($cells);
  583. $table = wf_TableBody($rows, '100%', 0);
  584. $inputs = $table;
  585. $inputs .= wf_Submit(__('Change'));
  586. $inputs .= wf_delimiter();
  587. $form = wf_Form("", 'POST', $inputs, '');
  588. return ($form);
  589. }
  590. /**
  591. * Returns all available tariff names
  592. *
  593. * @return array
  594. */
  595. function zb_TariffsGetAll() {
  596. $query = "SELECT `name` from `tariffs`";
  597. $alltariffs = simple_queryall($query);
  598. return ($alltariffs);
  599. }
  600. /**
  601. * Returns tariff selector with optional branches, lousy and stealth tariffs filtering
  602. *
  603. * @param string $fieldname
  604. * @param bool $skipLousy
  605. *
  606. * @return string
  607. */
  608. function web_tariffselector($fieldname = 'tariffsel', $skipLousy = false) {
  609. global $ubillingConfig;
  610. $altCfg = $ubillingConfig->getAlter();
  611. if ($altCfg['BRANCHES_ENABLED']) {
  612. global $branchControl;
  613. $branchControl->loadTariffs();
  614. }
  615. $alltariffs = zb_TariffsGetAll();
  616. $options = array();
  617. if (!empty($alltariffs)) {
  618. foreach ($alltariffs as $io => $eachtariff) {
  619. //validating tariff accessibility depend on branch if enabled
  620. if ($altCfg['BRANCHES_ENABLED']) {
  621. if ($branchControl->isMyTariff($eachtariff['name'])) {
  622. $options[$eachtariff['name']] = $eachtariff['name'];
  623. }
  624. } else {
  625. //or just append to list
  626. $options[$eachtariff['name']] = $eachtariff['name'];
  627. }
  628. }
  629. }
  630. //excluding lousy tariffs from list, if available
  631. if ($skipLousy) {
  632. $lousy = new LousyTariffs();
  633. $options = $lousy->truncateLousy($options);
  634. }
  635. //stealth tariffs implementation
  636. if ($altCfg['STEALTH_TARIFFS_ENABLED']) {
  637. $stealthTariffs = new StealthTariffs();
  638. //administrator have no rights to assign stealth tariffs?
  639. if (!cfr($stealthTariffs::RIGHT_STEALTH)) {
  640. //dropping all of them from selector options
  641. $options = $stealthTariffs->truncateStealth($options);
  642. }
  643. }
  644. $selector = wf_Selector($fieldname, $options, '', '', false);
  645. return ($selector);
  646. }
  647. /**
  648. * Returns full tariff changing form
  649. *
  650. * @global object $ubillingConfig
  651. * @param string $fieldname
  652. * @param string $fieldkey
  653. * @param string $useraddress
  654. * @param string $olddata
  655. * @param bool $skeepLousy
  656. *
  657. * @return string
  658. */
  659. function web_EditorTariffForm($fieldname, $fieldkey, $useraddress, $olddata = '', $skipLousy = false) {
  660. global $ubillingConfig;
  661. $alter = $ubillingConfig->getAlter();
  662. $login = (isset($_GET['username'])) ? vf($_GET['username']) : null;
  663. $nm_flag = ($olddata == '*_NO_TARIFF_*') ? 'DISABLED' : null;
  664. $charge_signup_price_checkbox = '';
  665. if (isset($alter['SIGNUP_PAYMENTS']) and !empty($alter['SIGNUP_PAYMENTS'])) {
  666. $payment = zb_UserGetSignupPrice($login);
  667. $paid = zb_UserGetSignupPricePaid($login);
  668. $disabled = ($payment == $paid and $payment > 0) ? 'disabled' : '';
  669. $charge_signup_price_checkbox = ' ' . wf_tag('label', false, '', 'for="charge_signup_price_checkbox"');
  670. $charge_signup_price_checkbox .= __('Charge signup price') . ' ';
  671. $charge_signup_price_checkbox .= wf_tag('input', false, '', 'type="checkbox" name="charge_signup_price" id="charge_signup_price_checkbox" ' . $disabled);
  672. $charge_signup_price_checkbox .= wf_tag('label', true);
  673. }
  674. $nmControl = wf_tag('label', false, '', 'for="nm"');
  675. $nmControl .= __('Next month');
  676. $nmControl .= wf_tag('input', false, '', 'type="checkbox" name="nextmonth" id="nm" ' . $nm_flag);
  677. $nmControl .= wf_tag('label', true);
  678. $cells = wf_TableCell(__('User'), '', 'row2');
  679. $cells .= wf_TableCell($useraddress, '', 'row3');
  680. $rows = wf_TableRow($cells);
  681. $cells = wf_TableCell($fieldname, '', 'row2');
  682. $cells .= wf_TableCell($olddata, '', 'row3');
  683. $rows .= wf_TableRow($cells);
  684. $cells = wf_TableCell($nmControl, '', 'row2', 'align="right"');
  685. $cells .= wf_TableCell(web_tariffselector($fieldkey, $skipLousy) . $charge_signup_price_checkbox, '', 'row3');
  686. $rows .= wf_TableRow($cells);
  687. $table = wf_TableBody($rows, '100%', 0);
  688. $inputs = $table;
  689. $inputs .= wf_tag('br');
  690. $inputs .= wf_Submit(__('Change'));
  691. $inputs .= wf_delimiter();
  692. $form = wf_Form('', 'POST', $inputs, '');
  693. return ($form);
  694. }
  695. /**
  696. * Returns two strings data grid editor (used in tariffspeeds)
  697. *
  698. * @param array $fieldnames
  699. * @param array $fieldkeys
  700. * @param array $olddata
  701. * @return string
  702. */
  703. function web_EditorTwoStringDataForm($fieldnames, $fieldkeys, $olddata) {
  704. $field1 = $fieldnames['fieldname1'];
  705. $field2 = $fieldnames['fieldname2'];
  706. $fieldkey1 = $fieldkeys['fieldkey1'];
  707. $fieldkey2 = $fieldkeys['fieldkey2'];
  708. $cells = wf_TableCell($field1, '', 'row2');
  709. $cells .= wf_TableCell(wf_TextInput($fieldkey1, '', $olddata[1], false, ''), '', 'row3');
  710. $rows = wf_TableRow($cells);
  711. $cells = wf_TableCell($field2, '', 'row2');
  712. $cells .= wf_TableCell(wf_TextInput($fieldkey2, '', $olddata[2], false, ''), '', 'row3');
  713. $rows .= wf_TableRow($cells);
  714. $table = wf_TableBody($rows, '100%', 0);
  715. $inputs = $table;
  716. $inputs .= wf_Submit(__('Change'));
  717. $inputs .= wf_delimiter();
  718. $form = wf_Form("", 'POST', $inputs, '');
  719. return ($form);
  720. }
  721. /**
  722. * Returns six strings data grid editor (used in tariffspeeds modified by Pautina)
  723. *
  724. * @param array $fieldnames
  725. * @param array $fieldkeys
  726. * @param array $olddata
  727. * @return string
  728. */
  729. function web_EditorSixStringDataForm($fieldnames, $fieldkeys, $olddata) {
  730. $field1 = $fieldnames['fieldname1'];
  731. $field2 = $fieldnames['fieldname2'];
  732. $field3 = $fieldnames['fieldname3'];
  733. $field4 = $fieldnames['fieldname4'];
  734. $field5 = $fieldnames['fieldname5'];
  735. $field6 = $fieldnames['fieldname6'];
  736. $fieldkey1 = $fieldkeys['fieldkey1'];
  737. $fieldkey2 = $fieldkeys['fieldkey2'];
  738. $fieldkey3 = $fieldkeys['fieldkey3'];
  739. $fieldkey4 = $fieldkeys['fieldkey4'];
  740. $fieldkey5 = $fieldkeys['fieldkey5'];
  741. $fieldkey6 = $fieldkeys['fieldkey6'];
  742. $cells = wf_TableCell($field1, '', 'row2');
  743. $cells .= wf_TableCell(wf_TextInput($fieldkey1, '', $olddata[1], false, ''), '', 'row3');
  744. $rows = wf_TableRow($cells);
  745. $cells = wf_TableCell($field2, '', 'row2');
  746. $cells .= wf_TableCell(wf_TextInput($fieldkey2, '', $olddata[2], false, ''), '', 'row3');
  747. $rows .= wf_TableRow($cells);
  748. $cells = wf_TableCell($field3, '', 'row2');
  749. $cells .= wf_TableCell(wf_TextInput($fieldkey3, '', $olddata[3], false, ''), '', 'row3');
  750. $rows .= wf_TableRow($cells);
  751. $cells = wf_TableCell($field4, '', 'row2');
  752. $cells .= wf_TableCell(wf_TextInput($fieldkey4, '', $olddata[4], false, ''), '', 'row3');
  753. $rows .= wf_TableRow($cells);
  754. $cells = wf_TableCell($field5, '', 'row2');
  755. $cells .= wf_TableCell(wf_TextInput($fieldkey5, '', $olddata[5], false, ''), '', 'row3');
  756. $rows .= wf_TableRow($cells);
  757. $cells = wf_TableCell($field6, '', 'row2');
  758. $cells .= wf_TableCell(wf_TextInput($fieldkey6, '', $olddata[6], false, ''), '', 'row3');
  759. $rows .= wf_TableRow($cells);
  760. $table = wf_TableBody($rows, '100%', 0);
  761. $inputs = $table;
  762. $inputs .= wf_Submit(__('Change'));
  763. $inputs .= wf_delimiter();
  764. $form = wf_Form("", 'POST', $inputs, '');
  765. return ($form);
  766. }
  767. /**
  768. * Translates payment notes into human-readable string
  769. *
  770. * @param string $paynote
  771. * @param array $allservicenames
  772. * @return string
  773. */
  774. function zb_TranslatePaymentNote($paynote, $allservicenames) {
  775. if ($paynote == '') {
  776. $paynote = __('Internet');
  777. }
  778. if (isset($allservicenames[$paynote])) {
  779. $paynote = $allservicenames[$paynote];
  780. }
  781. if (ispos($paynote, 'CARD:')) {
  782. $cardnum = explode(':', $paynote);
  783. $paynote = __('Card') . " " . $cardnum[1];
  784. }
  785. if (ispos($paynote, 'SCFEE')) {
  786. $paynote = __('Credit fee');
  787. }
  788. if (ispos($paynote, 'AFFEE')) {
  789. $paynote = __('Freezing fee');
  790. }
  791. if (ispos($paynote, 'TCHANGE:')) {
  792. $tariff = explode(':', $paynote);
  793. $paynote = __('Tariff change') . " " . $tariff[1];
  794. }
  795. if (ispos($paynote, 'BANKSTA:')) {
  796. $banksta = explode(':', $paynote);
  797. $paynote = __('Bank statement') . " " . $banksta[1];
  798. }
  799. if (ispos($paynote, 'MOCK:')) {
  800. $mock = explode(':', $paynote);
  801. $paynote = __('Mock payment') . ' ' . $mock[1];
  802. }
  803. if (ispos($paynote, 'BALANCESET:')) {
  804. $balset = explode(':', $paynote);
  805. $paynote = __('Set cash') . ' ' . $balset[1];
  806. }
  807. if (ispos($paynote, 'DISCOUNT:')) {
  808. $disountset = explode(':', $paynote);
  809. $paynote = __('Discount') . ' ' . $disountset[1] . '%';
  810. }
  811. if (ispos($paynote, 'PENALTY')) {
  812. $penalty = explode(':', $paynote);
  813. $paynote = __('Penalty') . ' ' . $penalty[1] . ' ' . __('days');
  814. }
  815. if (ispos($paynote, 'REMINDER')) {
  816. $paynote = __('SMS reminder activation');
  817. }
  818. if (ispos($paynote, 'FRIENDSHIP')) {
  819. $friendship = explode(':', $paynote);
  820. $paynote = __('Friendship') . ' ' . $friendship[1];
  821. }
  822. if (ispos($paynote, 'SCHEDULED')) {
  823. $paynote = __('Scheduled');
  824. }
  825. if (ispos($paynote, 'ECHARGE')) {
  826. $echarged = explode(':', $paynote);
  827. $paynote = __('Manually charged') . ' ' . $echarged[1];
  828. }
  829. if (ispos($paynote, 'DDT')) {
  830. $ddtcharged = explode(':', $paynote);
  831. $paynote = __('Doomsday tariff') . ': ' . $ddtcharged[1];
  832. }
  833. if (ispos($paynote, 'PTFEE')) {
  834. $paynote = __('PT') . ' ' . __('Fee');
  835. }
  836. if (ispos($paynote, 'EXTFEE')) {
  837. $paynote = __('External fee');
  838. }
  839. if (ispos($paynote, 'DEFSALE')) {
  840. $defsaleNote = explode(':', $paynote);
  841. $paynote = __('Deferred sale') . ': ' . $defsaleNote[1];
  842. }
  843. return ($paynote);
  844. }
  845. /**
  846. * Returns list of available tariffs speeds
  847. *
  848. * @return string
  849. */
  850. function web_TariffSpeedLister() {
  851. global $ubillingConfig;
  852. $altCfg = $ubillingConfig->getAlter();
  853. $results = '';
  854. $alltariffs = zb_TariffsGetAll();
  855. $availTariffs = array();
  856. $allspeeds = zb_TariffGetAllSpeeds();
  857. $cleanSpeedCount = 0;
  858. $cells = wf_TableCell(__('Tariff'));
  859. $cells .= wf_TableCell(__('Download speed'));
  860. $cells .= wf_TableCell(__('Upload speed'));
  861. if ($altCfg['BURST_ENABLED']) {
  862. $cells .= wf_TableCell(__('Burst Download speed'));
  863. $cells .= wf_TableCell(__('Burst Upload speed'));
  864. $cells .= wf_TableCell(__('Burst Download Time speed'));
  865. $cells .= wf_TableCell(__('Burst Upload Time speed'));
  866. }
  867. $cells .= wf_TableCell(__('Actions'));
  868. $rows = wf_TableRow($cells, 'row1');
  869. if (!empty($alltariffs)) {
  870. foreach ($alltariffs as $io => $eachtariff) {
  871. $availTariffs[$eachtariff['name']] = $eachtariff['name'];
  872. $cells = wf_TableCell($eachtariff['name']);
  873. $cells .= wf_TableCell(@$allspeeds[$eachtariff['name']]['speeddown']);
  874. $cells .= wf_TableCell(@$allspeeds[$eachtariff['name']]['speedup']);
  875. if ($altCfg['BURST_ENABLED']) {
  876. $cells .= wf_TableCell(@$allspeeds[$eachtariff['name']]['burstdownload']);
  877. $cells .= wf_TableCell(@$allspeeds[$eachtariff['name']]['burstupload']);
  878. $cells .= wf_TableCell(@$allspeeds[$eachtariff['name']]['bursttimedownload']);
  879. $cells .= wf_TableCell(@$allspeeds[$eachtariff['name']]['burstimetupload']);
  880. }
  881. $actLinks = wf_JSAlert('?module=tariffspeeds&tariff=' . $eachtariff['name'], web_edit_icon(), __('Are you serious'));
  882. $cells .= wf_TableCell($actLinks);
  883. $rows .= wf_TableRow($cells, 'row5');
  884. }
  885. }
  886. $result = wf_TableBody($rows, '100%', 0, 'sortable');
  887. if (!empty($allspeeds)) {
  888. $cells = wf_TableCell(__('Tariff') . ' (' . __('Deleted') . ')');
  889. $cells .= wf_TableCell(__('Download speed'));
  890. $cells .= wf_TableCell(__('Upload speed'));
  891. $cells .= wf_TableCell(__('Actions'));
  892. $rows = wf_TableRow($cells, 'row1');
  893. foreach ($allspeeds as $eachtariff => $eachspeed) {
  894. if (!isset($availTariffs[$eachtariff])) {
  895. $cells = wf_TableCell($eachtariff);
  896. $cells .= wf_TableCell($eachspeed['speeddown']);
  897. $cells .= wf_TableCell($eachspeed['speedup']);
  898. $cells .= wf_TableCell(wf_JSAlert('?module=tariffspeeds&deletespeed=' . $eachtariff, web_delete_icon(), __('Are you serious')));
  899. $rows .= wf_TableRow($cells, 'row3');
  900. $cleanSpeedCount++;
  901. }
  902. }
  903. if ($cleanSpeedCount != 0) {
  904. $result .= wf_delimiter();
  905. $result .= wf_tag('h3') . __('Database cleanup') . wf_tag('h3', true);
  906. $result .= wf_TableBody($rows, '100%', 0, 'sortable');
  907. }
  908. }
  909. return ($result);
  910. }
  911. /**
  912. * Returns an array with stargazer user data by some login
  913. *
  914. * @param string $login
  915. * @return array
  916. */
  917. function zb_ProfileGetStgData($login) {
  918. $login = vf($login);
  919. $query = "SELECT * from `users` WHERE `login`='" . $login . "'";
  920. $userdata = simple_query($query);
  921. return ($userdata);
  922. }
  923. /**
  924. * Returns all dates of admin actions (deprecated?)
  925. *
  926. * @return array
  927. */
  928. function zb_EventGetAllDateTimes() {
  929. $query = "SELECT `admin`,`date` from `weblogs`";
  930. $result = array();
  931. $allevents = simple_queryall($query);
  932. if (!empty($allevents)) {
  933. foreach ($allevents as $io => $eachevent) {
  934. $result[$eachevent['date']] = $eachevent['admin'];
  935. }
  936. }
  937. return ($result);
  938. }
  939. /**
  940. * Returns payment date editing form
  941. *
  942. * @param array $paymentData
  943. *
  944. * @return string
  945. */
  946. function web_PaymentEditForm($paymentData) {
  947. $result = '';
  948. if (!empty($paymentData)) {
  949. $paymentTimestamp = strtotime($paymentData['date']);
  950. $paymentDate = date("Y-m-d", $paymentTimestamp);
  951. $paymentDataBase = serialize($paymentData);
  952. $paymentDataBase = base64_encode($paymentDataBase);
  953. $inputs = '<!--ugly hack to prevent datepicker autoopen -->';
  954. $inputs .= wf_tag('input', false, '', 'type="text" name="shittyhack" style="width: 0; height: 0; top: -100px; position: absolute;"');
  955. $inputs .= wf_HiddenInput('editpaymentid', $paymentData['id']);
  956. $inputs .= wf_HiddenInput('paymentdata', $paymentDataBase);
  957. $cells = wf_TableCell(__('New date'), '', 'row2');
  958. $cells .= wf_TableCell(wf_DatePickerPreset('newpaymentdate', $paymentDate), '', 'row3');
  959. $rows = wf_TableRow($cells);
  960. if ($paymentData['admin'] != 'external' and $paymentData['admin'] != 'openpayz' and $paymentData['admin'] != 'guest') {
  961. $cells = wf_TableCell(__('Payment type'), '', 'row2');
  962. $cells .= wf_TableCell(web_CashTypeSelector($paymentData['cashtypeid']), '', 'row3');
  963. $rows .= wf_TableRow($cells);
  964. $cells = wf_TableCell(__('Payment notes'), '', 'row2');
  965. $cells .= wf_TableCell(wf_TextInput('paymentnote', '', $paymentData['note'], false, 40), '', 'row3');
  966. $rows .= wf_TableRow($cells);
  967. } else {
  968. $inputs .= wf_HiddenInput('cashtype', $paymentData['cashtypeid']);
  969. $inputs .= wf_HiddenInput('paymentnote', $paymentData['note']);
  970. }
  971. $table = wf_TableBody($rows, '100%', 0, '');
  972. $table .= wf_Submit(__('Save'));
  973. $form = $inputs;
  974. $form .= wf_Form('', 'POST', $table, '');
  975. $form .= wf_delimiter();
  976. $result = wf_Form('', 'POST', $form, 'glamour');
  977. }
  978. return ($result);
  979. }
  980. /**
  981. * Returns list of previous user payments
  982. *
  983. * @param string $login
  984. * @return string
  985. */
  986. function web_PaymentsByUser($login) {
  987. global $ubillingConfig;
  988. $allpayments = zb_CashGetUserPayments($login);
  989. $alter_conf = $ubillingConfig->getAlter();
  990. $alltypes = zb_CashGetAllCashTypes();
  991. $allservicenames = zb_VservicesGetAllNamesLabeled();
  992. $total_payments = 0;
  993. $curdate = curdate();
  994. $deletingAdmins = array();
  995. $editingAdmins = array();
  996. $iCanDeletePayments = false;
  997. $iCanEditPayments = false;
  998. $currentAdminLogin = whoami();
  999. $idencEnabled = (@$alter_conf['IDENC_ENABLED']) ? true : false;
  1000. //extract admin logins with payments delete rights
  1001. if (!empty($alter_conf['CAN_DELETE_PAYMENTS'])) {
  1002. $deletingAdmins = explode(',', $alter_conf['CAN_DELETE_PAYMENTS']);
  1003. $deletingAdmins = array_flip($deletingAdmins);
  1004. }
  1005. //extract admin logins with date edit rights
  1006. if (!empty($alter_conf['CAN_EDIT_PAYMENTS'])) {
  1007. $editingAdmins = explode(',', $alter_conf['CAN_EDIT_PAYMENTS']);
  1008. $editingAdmins = array_flip($editingAdmins);
  1009. }
  1010. //setting editing/deleting flags
  1011. $iCanDeletePayments = (isset($deletingAdmins[$currentAdminLogin])) ? true : false;
  1012. $iCanEditPayments = (isset($editingAdmins[$currentAdminLogin])) ? true : false;
  1013. $cells = wf_TableCell(__('ID'));
  1014. if ($idencEnabled) {
  1015. $cells .= wf_TableCell(__('IDENC'));
  1016. }
  1017. $cells .= wf_TableCell(__('Date'));
  1018. $cells .= wf_TableCell(__('Payment'));
  1019. $cells .= wf_TableCell(__('Balance before'));
  1020. $cells .= wf_TableCell(__('Cash type'));
  1021. $cells .= wf_TableCell(__('Payment note'));
  1022. $cells .= wf_TableCell(__('Admin'));
  1023. $cells .= wf_TableCell(__('Actions'));
  1024. $rows = wf_TableRow($cells, 'row1');
  1025. if (!empty($allpayments)) {
  1026. foreach ($allpayments as $eachpayment) {
  1027. //hightlight of today payments
  1028. if ($alter_conf['HIGHLIGHT_TODAY_PAYMENTS']) {
  1029. if (ispos($eachpayment['date'], $curdate)) {
  1030. $hlight = 'paytoday';
  1031. } else {
  1032. $hlight = 'row3';
  1033. }
  1034. } else {
  1035. $hlight = 'row3';
  1036. }
  1037. if (!empty($alter_conf['DOCX_SUPPORT']) and !empty($alter_conf['DOCX_CHECK'])) {
  1038. $printcheck = wf_Link('?module=printcheck&paymentid=' . $eachpayment['id'], wf_img('skins/printer_small.gif', __('Print')), false);
  1039. if (@$alter_conf['DOCX_CHECK_TH']) {
  1040. $printcheck .= wf_Link('?module=printcheck&th=true&paymentid=' . $eachpayment['id'], wf_img('skins/printer_small_blue.gif', __('Print')), false);
  1041. }
  1042. } else {
  1043. $printcheck = wf_tag('a', false, '', 'href="#" onClick="window.open(\'?module=printcheck&paymentid=' . $eachpayment['id'] . '\',\'checkwindow\',\'width=800,height=600\')"');
  1044. $printcheck .= wf_img('skins/printer_small.gif', __('Print'));
  1045. $printcheck .= wf_tag('a', true);
  1046. }
  1047. //payments deleting controls
  1048. if ($iCanDeletePayments) {
  1049. $deleteControls = wf_JSAlert('?module=addcash&username=' . $login . '&paymentdelete=' . $eachpayment['id'], wf_img('skins/delete_small.png', __('Delete')), __('Removing this may lead to irreparable results')) . ' &nbsp; ';
  1050. } else {
  1051. $deleteControls = '';
  1052. }
  1053. //payments editing form
  1054. if ($iCanEditPayments) {
  1055. $editControls = wf_modalAuto(wf_img_sized('skins/icon_edit.gif', __('Edit'), '10'), __('Edit'), web_PaymentEditForm($eachpayment), '') . ' &nbsp; ';
  1056. } else {
  1057. $editControls = '';
  1058. }
  1059. if ($alter_conf['TRANSLATE_PAYMENTS_NOTES']) {
  1060. $eachpayment['note'] = zb_TranslatePaymentNote($eachpayment['note'], $allservicenames);
  1061. }
  1062. $cells = wf_TableCell($eachpayment['id']);
  1063. if ($idencEnabled) {
  1064. $cells .= wf_TableCell(zb_NumEncode($eachpayment['id']));
  1065. }
  1066. $cells .= wf_TableCell($eachpayment['date']);
  1067. $cells .= wf_TableCell($eachpayment['summ']);
  1068. $cells .= wf_TableCell($eachpayment['balance']);
  1069. $cells .= wf_TableCell(@__($alltypes[$eachpayment['cashtypeid']]));
  1070. $cells .= wf_TableCell($eachpayment['note']);
  1071. $cells .= wf_TableCell($eachpayment['admin']);
  1072. $cells .= wf_TableCell($deleteControls . $editControls . $printcheck);
  1073. $rows .= wf_TableRow($cells, $hlight);
  1074. if (is_numeric($eachpayment['summ'])) {
  1075. if ($eachpayment['summ'] > 0) {
  1076. $total_payments = $total_payments + $eachpayment['summ'];
  1077. }
  1078. }
  1079. }
  1080. }
  1081. $result = wf_TableBody($rows, '100%', '0', 'sortable');
  1082. $result .= __('Total payments') . ': ' . wf_tag('b') . abs($total_payments) . wf_tag('b') . wf_tag('br');
  1083. return ($result);
  1084. }
  1085. /**
  1086. * Returns actions performed on user parsed from log
  1087. *
  1088. * @param string $login
  1089. * @param bool $strict
  1090. * @return string
  1091. */
  1092. function web_GrepLogByUser($login, $strict = false) {
  1093. $login = ($strict) ? '(' . $login . ')' : $login;
  1094. @$employeeNames = unserialize(ts_GetAllEmployeeLoginsCached());
  1095. $query = 'SELECT * from `weblogs` WHERE `event` LIKE "%' . $login . '%" ORDER BY `date` DESC';
  1096. $allevents = simple_queryall($query);
  1097. $cells = wf_TableCell(__('ID'));
  1098. $cells .= wf_TableCell(__('Who?'));
  1099. $cells .= wf_TableCell(__('When?'));
  1100. $cells .= wf_TableCell(__('What happen?'));
  1101. $rows = wf_TableRow($cells, 'row1');
  1102. if (!empty($allevents)) {
  1103. foreach ($allevents as $io => $eachevent) {
  1104. $adminName = (isset($employeeNames[$eachevent['admin']])) ? $employeeNames[$eachevent['admin']] : $eachevent['admin'];
  1105. $idLabel = wf_tag('abbr', false, '', 'title="' . $eachevent['ip'] . '"') . $eachevent['id'] . wf_tag('abbr', true);
  1106. $cells = wf_TableCell($idLabel);
  1107. $cells .= wf_TableCell($adminName);
  1108. $cells .= wf_TableCell($eachevent['date']);
  1109. $cells .= wf_TableCell($eachevent['event']);
  1110. $rows .= wf_TableRow($cells, 'row5');
  1111. }
  1112. }
  1113. $result = wf_TableBody($rows, '100%', 0, 'sortable');
  1114. return ($result);
  1115. }
  1116. /**
  1117. * Cash types one sting data editor
  1118. *
  1119. * @param string $fieldname
  1120. * @param string $fieldkey
  1121. * @param string $formurl
  1122. * @param array $olddata
  1123. * @return string
  1124. */
  1125. function web_EditorTableDataFormOneField($fieldname, $fieldkey, $formurl, $olddata) {
  1126. $cells = wf_TableCell(__('ID'));
  1127. $cells .= wf_TableCell(__($fieldname));
  1128. $cells .= wf_TableCell(__('Actions'));
  1129. $rows = wf_TableRow($cells, 'row1');
  1130. if (!empty($olddata)) {
  1131. foreach ($olddata as $io => $value) {
  1132. $cells = wf_TableCell($value['id']);
  1133. $cells .= wf_TableCell($value[$fieldkey]);
  1134. $actLinks = wf_JSAlert($formurl . '&action=delete&id=' . $value['id'], web_delete_icon(), 'Removing this may lead to irreparable results') . ' ';
  1135. $actLinks .= wf_Link($formurl . '&action=edit&id=' . $value['id'], web_edit_icon(), false);
  1136. $cells .= wf_TableCell($actLinks);
  1137. $rows .= wf_TableRow($cells, 'row3');
  1138. }
  1139. }
  1140. $table = wf_TableBody($rows, '100%', 0, 'sortable');
  1141. $inputs = wf_TextInput('new' . $fieldkey, __($fieldname), '', false);
  1142. $inputs .= wf_Submit(__('Create'));
  1143. $form = wf_Form('', 'POST', $inputs, 'glamour');
  1144. return ($table . $form);
  1145. }
  1146. /**
  1147. * Retuns year selector. Is here, only for backward compatibility with old modules.
  1148. * use only wf_YearSelector() in new code.
  1149. *
  1150. * @return string
  1151. */
  1152. function web_year_selector() {
  1153. $selector = wf_YearSelector('yearsel');
  1154. return ($selector);
  1155. }
  1156. /**
  1157. * Shows list for available traffic classes
  1158. *
  1159. * @return void
  1160. */
  1161. function web_DirectionsShow() {
  1162. $allrules = zb_DirectionsGetAll();
  1163. $cells = wf_TableCell(__('Rule number'));
  1164. $cells .= wf_TableCell(__('Rule name'));
  1165. $cells .= wf_TableCell(__('Actions'));
  1166. $rows = wf_TableRow($cells, 'row1');
  1167. if (!empty($allrules)) {
  1168. foreach ($allrules as $io => $eachrule) {
  1169. $cells = wf_TableCell($eachrule['rulenumber']);
  1170. $cells .= wf_TableCell($eachrule['rulename']);
  1171. $actLinks = wf_JSAlert('?module=rules&delete=' . $eachrule['id'], web_delete_icon(), 'Removing this may lead to irreparable results') . ' ';
  1172. $actLinks .= wf_JSAlert("?module=rules&edit=" . $eachrule['id'], web_edit_icon(), 'Are you serious');
  1173. $cells .= wf_TableCell($actLinks);
  1174. $rows .= wf_TableRow($cells, 'row3');
  1175. }
  1176. }
  1177. $result = wf_TableBody($rows, '100%', 0, 'sortable');
  1178. show_window(__('Traffic classes'), $result);
  1179. }
  1180. /**
  1181. * Shows traffic class adding form
  1182. *
  1183. * @return void
  1184. */
  1185. function web_DirectionAddForm() {
  1186. $allrules = zb_DirectionsGetAll();
  1187. $availrules = array();
  1188. $selectArr = array();
  1189. if (!empty($allrules)) {
  1190. foreach ($allrules as $io => $eachrule) {
  1191. $availrules[$eachrule['rulenumber']] = $eachrule['rulename'];
  1192. }
  1193. }
  1194. for ($i = 0; $i <= 9; $i++) {
  1195. if (!isset($availrules[$i])) {
  1196. $selectArr[$i] = $i;
  1197. }
  1198. }
  1199. $inputs = wf_Selector('newrulenumber', $selectArr, __('Direction number'), '', true);
  1200. $inputs .= wf_TextInput('newrulename', __('Direction name'), '', true);
  1201. $inputs .= wf_Submit(__('Create'));
  1202. $form = wf_Form('', 'POST', $inputs, 'glamour');
  1203. show_window(__('Add new traffic class'), $form);
  1204. }
  1205. /**
  1206. * Shows traffic class edit form
  1207. *
  1208. * @param int $ruleid
  1209. *
  1210. * @return void
  1211. */
  1212. function web_DirectionsEditForm($ruleid) {
  1213. $ruleid = vf($ruleid, 3);
  1214. $query = "SELECT * from `directions` WHERE `id`='" . $ruleid . "'";
  1215. $ruledata = simple_query($query);
  1216. $editinputs = wf_TextInput('editrulename', 'Rule name', $ruledata['rulename'], true, '20');
  1217. $editinputs .= wf_Submit('Save');
  1218. $editform = wf_Form("", 'POST', $editinputs, 'glamour');
  1219. $editform .= wf_BackLink('?module=rules');
  1220. show_window(__('Edit') . ' ' . __('Rule name'), $editform);
  1221. }
  1222. /**
  1223. * Renders some content with title in floating containers.
  1224. *
  1225. * @param string $title
  1226. * @param string $content
  1227. *
  1228. * @return string
  1229. */
  1230. function web_FinRepControls($title = '', $content) {
  1231. $result = '';
  1232. $style = 'style="float:left; display:block; height:90px; margin-right: 20px;"';
  1233. $result .= wf_tag('div', false, '', $style);
  1234. $result .= wf_tag('h3') . $title . wf_tag('h3', true);
  1235. $result .= wf_tag('br');
  1236. $result .= $content;
  1237. $result .= wf_tag('div', true);
  1238. return ($result);
  1239. }
  1240. /**
  1241. * Renders payments extracted from database with some query
  1242. *
  1243. * @param string $query
  1244. * @return string
  1245. */
  1246. function web_PaymentsShow($query) {
  1247. global $ubillingConfig;
  1248. $alter_conf = $ubillingConfig->getAlter();
  1249. $alladrs = zb_AddressGetFulladdresslistCached();
  1250. $allrealnames = zb_UserGetAllRealnames();
  1251. $alltypes = zb_CashGetAllCashTypes();
  1252. $allapayments = simple_queryall($query);
  1253. $allservicenames = zb_VservicesGetAllNamesLabeled();
  1254. $idencEnabled = (@$alter_conf['IDENC_ENABLED']) ? true : false;
  1255. //getting full contract list
  1256. if ($alter_conf['FINREP_CONTRACT']) {
  1257. $allcontracts = zb_UserGetAllContracts();
  1258. $allcontracts = array_flip($allcontracts);
  1259. }
  1260. //getting all users tariffs
  1261. if ($alter_conf['FINREP_TARIFF']) {
  1262. $alltariffs = zb_TariffsGetAllUsers();
  1263. }
  1264. $total = 0;
  1265. $totalPaycount = 0;
  1266. $cells = wf_TableCell(__('ID'));
  1267. if ($idencEnabled) {
  1268. $cells .= wf_TableCell(__('IDENC'));
  1269. }
  1270. $cells .= wf_TableCell(__('Date'));
  1271. $cells .= wf_TableCell(__('Cash'));
  1272. //optional contract display
  1273. if ($alter_conf['FINREP_CONTRACT']) {
  1274. $cells .= wf_TableCell(__('Contract'));
  1275. }
  1276. $cells .= wf_TableCell(__('Login'));
  1277. $cells .= wf_TableCell(__('Full address'));
  1278. $cells .= wf_TableCell(__('Real Name'));
  1279. //optional tariff display
  1280. if ($alter_conf['FINREP_TARIFF']) {
  1281. $cells .= wf_TableCell(__('Tariff'));
  1282. }
  1283. $cells .= wf_TableCell(__('Cash type'));
  1284. $cells .= wf_TableCell(__('Notes'));
  1285. $cells .= wf_TableCell(__('Admin'));
  1286. $rows = wf_TableRow($cells, 'row1');
  1287. if (!empty($allapayments)) {
  1288. foreach ($allapayments as $io => $eachpayment) {
  1289. if ($alter_conf['TRANSLATE_PAYMENTS_NOTES']) {
  1290. $eachpayment['note'] = zb_TranslatePaymentNote($eachpayment['note'], $allservicenames);
  1291. }
  1292. $cells = wf_TableCell($eachpayment['id']);
  1293. if ($idencEnabled) {
  1294. $cells .= wf_TableCell(zb_NumEncode($eachpayment['id']));
  1295. }
  1296. $cells .= wf_TableCell($eachpayment['date']);
  1297. $cells .= wf_TableCell($eachpayment['summ']);
  1298. //optional contract display
  1299. if ($alter_conf['FINREP_CONTRACT']) {
  1300. $cells .= wf_TableCell(@$allcontracts[$eachpayment['login']]);
  1301. }
  1302. $cells .= wf_TableCell(wf_Link('?module=userprofile&username=' . $eachpayment['login'], (web_profile_icon() . ' ' . $eachpayment['login']), false, ''));
  1303. $cells .= wf_TableCell(@$alladrs[$eachpayment['login']]);
  1304. $cells .= wf_TableCell(@$allrealnames[$eachpayment['login']]);
  1305. //optional tariff display
  1306. if ($alter_conf['FINREP_TARIFF']) {
  1307. $cells .= wf_TableCell(@$alltariffs[$eachpayment['login']]);
  1308. }
  1309. $cells .= wf_TableCell(@__($alltypes[$eachpayment['cashtypeid']]));
  1310. $cells .= wf_TableCell($eachpayment['note']);
  1311. $cells .= wf_TableCell($eachpayment['admin']);
  1312. $rows .= wf_TableRow($cells, 'row3');
  1313. if ($eachpayment['summ'] > 0) {
  1314. $total = $total + $eachpayment['summ'];
  1315. $totalPaycount++;
  1316. }
  1317. }
  1318. }
  1319. $result = wf_TableBody($rows, '100%', '0', 'sortable');
  1320. $result .= wf_tag('strong') . __('Cash') . ': ' . $total . wf_tag('strong', true) . wf_tag('br');
  1321. $result .= wf_tag('strong') . __('Count') . ': ' . $totalPaycount . wf_tag('strong', true);
  1322. return ($result);
  1323. }
  1324. /**
  1325. * Returns visual bar with count/total proportional size
  1326. *
  1327. * @param float $count
  1328. * @param float $total
  1329. * @return string
  1330. */
  1331. function web_bar($count, $total) {
  1332. $barurl = 'skins/bar.png';
  1333. if ($total != 0) {
  1334. $width = ($count / $total) * 100;
  1335. } else {
  1336. $width = 0;
  1337. }
  1338. $code = wf_img_sized($barurl, '', $width . '%', '14');
  1339. return ($code);
  1340. }
  1341. /**
  1342. * Returns all months with names in two digit notation
  1343. *
  1344. * @param string $number
  1345. * @return array/string
  1346. */
  1347. function months_array($number = null) {
  1348. $months = array(
  1349. '01' => 'January',
  1350. '02' => 'February',
  1351. '03' => 'March',
  1352. '04' => 'April',
  1353. '05' => 'May',
  1354. '06' => 'June',
  1355. '07' => 'July',
  1356. '08' => 'August',
  1357. '09' => 'September',
  1358. '10' => 'October',
  1359. '11' => 'November',
  1360. '12' => 'December'
  1361. );
  1362. if (empty($number)) {
  1363. return $months;
  1364. } else {
  1365. return $months[$number];
  1366. }
  1367. }
  1368. /**
  1369. * Returns localized array of days of week as dayNumber=>dayName
  1370. *
  1371. * @param bool $any add any day of week as 1488 number of day
  1372. *
  1373. * @return array
  1374. */
  1375. function daysOfWeek($any = false) {
  1376. $result = array();
  1377. if ($any) {
  1378. $result[1488] = __('Any');
  1379. }
  1380. $result[1] = rcms_date_localise('Monday');
  1381. $result[2] = rcms_date_localise('Tuesday');
  1382. $result[3] = rcms_date_localise('Wednesday');
  1383. $result[4] = rcms_date_localise('Thursday');
  1384. $result[5] = rcms_date_localise('Friday');
  1385. $result[6] = rcms_date_localise('Saturday');
  1386. $result[7] = rcms_date_localise('Sunday');
  1387. return ($result);
  1388. }
  1389. /**
  1390. * Retuns all months with names without begin zeros
  1391. *
  1392. * @return array
  1393. */
  1394. function months_array_wz() {
  1395. $months = array(
  1396. '1' => 'January',
  1397. '2' => 'February',
  1398. '3' => 'March',
  1399. '4' => 'April',
  1400. '5' => 'May',
  1401. '6' => 'June',
  1402. '7' => 'July',
  1403. '8' => 'August',
  1404. '9' => 'September',
  1405. '10' => 'October',
  1406. '11' => 'November',
  1407. '12' => 'December'
  1408. );
  1409. return ($months);
  1410. }
  1411. /**
  1412. * Returns all months with names in two digit notation
  1413. *
  1414. * @return array
  1415. */
  1416. function months_array_localized() {
  1417. $months = months_array();
  1418. $result = array();
  1419. if (!empty($months)) {
  1420. foreach ($months as $io => $each) {
  1421. $result[$io] = rcms_date_localise($each);
  1422. }
  1423. }
  1424. return ($result);
  1425. }
  1426. /**
  1427. * Allocates array with full timeline as hh:mm=>0
  1428. *
  1429. * @return array
  1430. */
  1431. function allocDayTimeline() {
  1432. $result = array();
  1433. for ($h = 0; $h <= 23; $h++) {
  1434. for ($m = 0; $m < 60; $m++) {
  1435. $hLabel = ($h > 9) ? $h : '0' . $h;
  1436. $mLabel = ($m > 9) ? $m : '0' . $m;
  1437. $timeLabel = $hLabel . ':' . $mLabel;
  1438. $result[$timeLabel] = 0;
  1439. }
  1440. }
  1441. return ($result);
  1442. }
  1443. /**
  1444. * Shows payments year graph with caching
  1445. *
  1446. * @param int $year
  1447. */
  1448. function web_PaymentsShowGraph($year) {
  1449. global $ubillingConfig;
  1450. $months = months_array();
  1451. $year_summ = zb_PaymentsGetYearSumm($year);
  1452. $curtime = time();
  1453. $yearPayData = array();
  1454. $yearStats = array();
  1455. $cache = new UbillingCache();
  1456. $cacheTime = 3600; //sec intervall to cache
  1457. $cells = wf_TableCell('');
  1458. $cells .= wf_TableCell(__('Month'));
  1459. $cells .= wf_TableCell(__('Payments count'));
  1460. $cells .= wf_TableCell(__('ARPU'));
  1461. $cells .= wf_TableCell(__('Cash'));
  1462. $cells .= wf_TableCell(__('Visual'), '50%');
  1463. $rows = wf_TableRow($cells, 'row1');
  1464. //caching subroutine
  1465. $renewTime = $cache->get('YPD_LAST', $cacheTime);
  1466. if (empty($renewTime)) {
  1467. //first usage
  1468. $renewTime = $curtime;
  1469. $cache->set('YPD_LAST', $renewTime, $cacheTime);
  1470. $updateCache = true;
  1471. } else {
  1472. //cache time already set
  1473. $timeShift = $curtime - $renewTime;
  1474. if ($timeShift > $cacheTime) {
  1475. //cache update needed
  1476. $updateCache = true;
  1477. } else {
  1478. //load data from cache or init new cache
  1479. $yearPayData_raw = $cache->get('YPD_CACHE', $cacheTime);
  1480. if (empty($yearPayData_raw)) {
  1481. //first usage
  1482. $emptyCache = array();
  1483. $emptyCache = serialize($emptyCache);
  1484. $emptyCache = base64_encode($emptyCache);
  1485. $cache->set('YPD_CACHE', $emptyCache, $cacheTime);
  1486. $updateCache = true;
  1487. } else {
  1488. // data loaded from cache
  1489. $yearPayData = base64_decode($yearPayData_raw);
  1490. $yearPayData = unserialize($yearPayData);
  1491. $updateCache = false;
  1492. //check is current year already cached?
  1493. if (!isset($yearPayData[$year]['graphs'])) {
  1494. $updateCache = true;
  1495. }
  1496. //check is manual cache refresh is needed?
  1497. if (wf_CheckGet(array('forcecache'))) {
  1498. $updateCache = true;
  1499. rcms_redirect("?module=report_finance");
  1500. }
  1501. }
  1502. }
  1503. }
  1504. if ($updateCache) {
  1505. $dopWhere = '';
  1506. if ($ubillingConfig->getAlterParam('REPORT_FINANCE_IGNORE_ID')) {
  1507. $exIdArr = array_map('trim', explode(',', $ubillingConfig->getAlterParam('REPORT_FINANCE_IGNORE_ID')));
  1508. $exIdArr = array_filter($exIdArr);
  1509. // Create and WHERE to query
  1510. if (!empty($exIdArr)) {
  1511. $dopWhere = ' AND ';
  1512. $dopWhere .= ' `cashtypeid` != ' . implode(' AND `cashtypeid` != ', $exIdArr);
  1513. }
  1514. }
  1515. //extracting all of needed payments in one query
  1516. if ($ubillingConfig->getAlterParam('REPORT_FINANCE_CONSIDER_NEGATIVE')) {
  1517. // ugly way to get payments with negative sums
  1518. // performance degradation is kinda twice
  1519. $allYearPayments_q = "(SELECT * FROM `payments`
  1520. WHERE `date` LIKE '" . $year . "-%' AND `summ` < '0'
  1521. AND note NOT LIKE 'Service:%'
  1522. AND note NOT LIKE 'PENALTY%'
  1523. AND note NOT LIKE 'OMEGATV%'
  1524. AND note NOT LIKE 'MEGOGO%'
  1525. AND note NOT LIKE 'TRINITYTV%' " . $dopWhere . ")
  1526. UNION ALL
  1527. (SELECT * FROM `payments` WHERE `date` LIKE '" . $year . "-%' AND `summ` > '0' " . $dopWhere . ")";
  1528. } else {
  1529. $allYearPayments_q = "SELECT * FROM `payments` WHERE `date` LIKE '" . $year . "-%' AND `summ` > '0' " . $dopWhere;
  1530. }
  1531. $allYearPayments = simple_queryall($allYearPayments_q);
  1532. if (!empty($allYearPayments)) {
  1533. foreach ($allYearPayments as $idx => $eachYearPayment) {
  1534. //Here we can get up to 50% of CPU time on month extraction, but this hacks is to ugly :(
  1535. //Benchmark results: http://pastebin.com/i7kadpN7
  1536. $statsMonth = date("m", strtotime($eachYearPayment['date']));
  1537. if (isset($yearStats[$statsMonth])) {
  1538. $yearStats[$statsMonth]['count']++;
  1539. $yearStats[$statsMonth]['summ'] = $yearStats[$statsMonth]['summ'] + $eachYearPayment['summ'];
  1540. } else {
  1541. $yearStats[$statsMonth]['count'] = 1;
  1542. $yearStats[$statsMonth]['summ'] = $eachYearPayment['summ'];
  1543. }
  1544. }
  1545. }
  1546. foreach ($months as $eachmonth => $monthname) {
  1547. $month_summ = (isset($yearStats[$eachmonth])) ? $yearStats[$eachmonth]['summ'] : 0;
  1548. $paycount = (isset($yearStats[$eachmonth])) ? $yearStats[$eachmonth]['count'] : 0;
  1549. if ($paycount != 0) {
  1550. $monthArpu = @round($month_summ / $paycount, 2);
  1551. } else {
  1552. $monthArpu = 0;
  1553. }
  1554. if (is_nan($monthArpu)) {
  1555. $monthArpu = 0;
  1556. }
  1557. $cells = wf_TableCell($eachmonth);
  1558. $cells .= wf_TableCell(wf_Link('?module=report_finance&month=' . $year . '-' . $eachmonth, rcms_date_localise($monthname)));
  1559. $cells .= wf_TableCell($paycount);
  1560. $cells .= wf_TableCell($monthArpu);
  1561. $cells .= wf_TableCell(zb_CashBigValueFormat($month_summ), '', '', 'align="right"');
  1562. $cells .= wf_TableCell(web_bar($month_summ, $year_summ), '', '', 'sorttable_customkey="' . $month_summ . '"');
  1563. $rows .= wf_TableRow($cells, 'row3');
  1564. }
  1565. $result = wf_TableBody($rows, '100%', '0', 'sortable');
  1566. $yearPayData[$year]['graphs'] = $result;
  1567. //write to cache
  1568. $cache->set('YPD_LAST', $curtime, $cacheTime);
  1569. $newCache = serialize($yearPayData);
  1570. $newCache = base64_encode($newCache);
  1571. $cache->set('YPD_CACHE', $newCache, $cacheTime);
  1572. } else {
  1573. //take data from cache
  1574. if (isset($yearPayData[$year]['graphs'])) {
  1575. $result = $yearPayData[$year]['graphs'];
  1576. $result .= __('Cache state at time') . ': ' . date("Y-m-d H:i:s", ($renewTime)) . ' ';
  1577. $result .= wf_Link("?module=report_finance&forcecache=true", wf_img('skins/icon_cleanup.png', __('Renew')), false, '');
  1578. } else {
  1579. $result = __('Strange exeption');
  1580. }
  1581. }
  1582. $winControl = '';
  1583. if ($ubillingConfig->getAlterParam('BRANCHES_ENABLED')) {
  1584. $winControl .= wf_Link('?module=report_finance&branchreport=true', wf_img_sized('skins/icon_branch.png', __('Branches'), 12)) . ' ';
  1585. }
  1586. show_window($winControl . __('Payments by') . ' ' . $year, $result);
  1587. }
  1588. /**
  1589. * Shows payments year graph with caching
  1590. *
  1591. * @param int $year
  1592. */
  1593. function web_PaymentsShowGraphPerBranch($year) {
  1594. global $ubillingConfig;
  1595. $months = months_array();
  1596. $year_summ = zb_PaymentsGetYearSumm($year);
  1597. $curtime = time();
  1598. $yearPayData = array();
  1599. $yearStats = array();
  1600. $result = '';
  1601. $branches = new UbillingBranches();
  1602. $allBranches[0] = __('No');
  1603. $allBranches += $branches->getBranchesAvailable();
  1604. $dopWhere = '';
  1605. if ($ubillingConfig->getAlterParam('REPORT_FINANCE_IGNORE_ID')) {
  1606. $exIdArr = array_map('trim', explode(',', $ubillingConfig->getAlterParam('REPORT_FINANCE_IGNORE_ID')));
  1607. $exIdArr = array_filter($exIdArr);
  1608. // Create and WHERE to query
  1609. if (!empty($exIdArr)) {
  1610. $dopWhere = ' AND ';
  1611. $dopWhere .= ' `cashtypeid` != ' . implode(' AND `cashtypeid` != ', $exIdArr);
  1612. }
  1613. }
  1614. //extracting all of needed payments in one query
  1615. if ($ubillingConfig->getAlterParam('REPORT_FINANCE_CONSIDER_NEGATIVE')) {
  1616. // ugly way to get payments with negative sums
  1617. // performance degradation is kinda twice
  1618. $allYearPayments_q = "(SELECT * FROM `payments`
  1619. WHERE `date` LIKE '" . $year . "-%' AND `summ` < '0'
  1620. AND note NOT LIKE 'Service:%'
  1621. AND note NOT LIKE 'PENALTY%'
  1622. AND note NOT LIKE 'OMEGATV%'
  1623. AND note NOT LIKE 'MEGOGO%'
  1624. AND note NOT LIKE 'TRINITYTV%' " . $dopWhere . ")
  1625. UNION ALL
  1626. (SELECT * FROM `payments` WHERE `date` LIKE '" . $year . "-%' AND `summ` > '0' " . $dopWhere . ")";
  1627. } else {
  1628. $allYearPayments_q = "SELECT * FROM `payments` WHERE `date` LIKE '" . $year . "-%' AND `summ` > '0' " . $dopWhere;
  1629. }
  1630. $allYearPayments = simple_queryall($allYearPayments_q);
  1631. if (!empty($allYearPayments)) {
  1632. foreach ($allYearPayments as $idx => $eachYearPayment) {
  1633. $userBranchId = $branches->userGetBranch($eachYearPayment['login']);
  1634. if (empty($userBranchId)) {
  1635. $userBranchId = 0;
  1636. }
  1637. $statsMonth = date("m", strtotime($eachYearPayment['date']));
  1638. if (isset($yearStats[$userBranchId][$statsMonth])) {
  1639. $yearStats[$userBranchId][$statsMonth]['count']++;
  1640. $yearStats[$userBranchId][$statsMonth]['summ'] = $yearStats[$userBranchId][$statsMonth]['summ'] + $eachYearPayment['summ'];
  1641. } else {
  1642. $yearStats[$userBranchId][$statsMonth]['count'] = 1;
  1643. $yearStats[$userBranchId][$statsMonth]['summ'] = $eachYearPayment['summ'];
  1644. }
  1645. }
  1646. }
  1647. foreach ($allBranches as $eachBranchId => $eachBranchName) {
  1648. $branchTotalSumm = 0;
  1649. $result .= wf_tag('strong') . __('Branch') . ': ' . $eachBranchName . wf_tag('strong', true);
  1650. $result .= wf_tag('br');
  1651. $cells = wf_TableCell('');
  1652. $cells .= wf_TableCell(__('Month'));
  1653. $cells .= wf_TableCell(__('Payments count'));
  1654. $cells .= wf_TableCell(__('ARPU'));
  1655. $cells .= wf_TableCell(__('Cash'));
  1656. $cells .= wf_TableCell(__('Visual'), '50%');
  1657. $rows = wf_TableRow($cells, 'row1');
  1658. foreach ($months as $eachmonth => $monthname) {
  1659. $month_summ = (isset($yearStats[$eachBranchId][$eachmonth])) ? $yearStats[$eachBranchId][$eachmonth]['summ'] : 0;
  1660. $paycount = (isset($yearStats[$eachBranchId][$eachmonth])) ? $yearStats[$eachBranchId][$eachmonth]['count'] : 0;
  1661. $monthArpu = @round($month_summ / $paycount, 2);
  1662. $branchTotalSumm += $month_summ;
  1663. if (is_nan($monthArpu)) {
  1664. $monthArpu = 0;
  1665. }
  1666. $cells = wf_TableCell($eachmonth);
  1667. $cells .= wf_TableCell(rcms_date_localise($monthname));
  1668. $cells .= wf_TableCell($paycount);
  1669. $cells .= wf_TableCell($monthArpu);
  1670. $cells .= wf_TableCell(zb_CashBigValueFormat($month_summ), '', '', 'align="right"');
  1671. $cells .= wf_TableCell(web_bar($month_summ, $year_summ), '', '', 'sorttable_customkey="' . $month_summ . '"');
  1672. $rows .= wf_TableRow($cells, 'row3');
  1673. }
  1674. $result .= wf_TableBody($rows, '100%', '0', 'sortable');
  1675. $result .= __('Total money') . ': ' . zb_CashBigValueFormat($branchTotalSumm);
  1676. $result .= wf_delimiter();
  1677. }
  1678. $winControl = '';
  1679. if ($ubillingConfig->getAlterParam('BRANCHES_ENABLED')) {
  1680. $winControl .= wf_Link('?module=report_finance', wf_img_sized('skins/icon_dollar_16.gif', __('Normal'), 12)) . ' ';
  1681. }
  1682. show_window($winControl . __('Payments by') . ' ' . $year . ' / ' . __('Branches'), $result);
  1683. }
  1684. /**
  1685. * Returns editor for some array data.
  1686. *
  1687. * @param array $titles
  1688. * @param array $keys
  1689. * @param array $alldata
  1690. * @param string $module
  1691. * @param bool $delete
  1692. * @param bool $edit
  1693. * @param string $prefix
  1694. * @param string $extaction
  1695. * @param string $extbutton
  1696. * @param bool $emptyWarning
  1697. *
  1698. * @return string
  1699. */
  1700. function web_GridEditor($titles, $keys, $alldata, $module, $delete = true, $edit = false, $prefix = '', $extaction = '', $extbutton = '', $emptyWarning = false) {
  1701. $result = '';
  1702. //headers
  1703. $cells = '';
  1704. foreach ($titles as $eachtitle) {
  1705. $cells .= wf_TableCell(__($eachtitle));
  1706. }
  1707. $cells .= wf_TableCell(__('Actions'));
  1708. $rows = wf_TableRow($cells, 'row1');
  1709. //headers end
  1710. $cells = '';
  1711. if (!empty($alldata)) {
  1712. foreach ($alldata as $io => $eachdata) {
  1713. $cells = '';
  1714. foreach ($keys as $eachkey) {
  1715. if (array_key_exists($eachkey, $eachdata)) {
  1716. $cells .= wf_TableCell($eachdata[$eachkey]);
  1717. }
  1718. }
  1719. if ($delete) {
  1720. $deletecontrol = wf_JSAlert('?module=' . $module . '&' . $prefix . 'delete=' . $eachdata['id'], web_delete_icon(), 'Removing this may lead to irreparable results');
  1721. } else {
  1722. $deletecontrol = '';
  1723. }
  1724. if ($edit) {
  1725. $editcontrol = wf_Link('?module=' . $module . '&' . $prefix . 'edit=' . $eachdata['id'], web_edit_icon(), false);
  1726. } else {
  1727. $editcontrol = '';
  1728. }
  1729. if (!empty($extaction)) {
  1730. $extencontrol = wf_Link('?module=' . $module . '&' . $prefix . $extaction . '=' . $eachdata['id'], $extbutton, false);
  1731. } else {
  1732. $extencontrol = '';
  1733. }
  1734. $cells .= wf_TableCell($deletecontrol . ' ' . $editcontrol . ' ' . $extencontrol);
  1735. $rows .= wf_TableRow($cells, 'row5');
  1736. }
  1737. }
  1738. $result .= wf_TableBody($rows, '100%', 0, 'sortable');
  1739. //override result with empty notice if required
  1740. if ($emptyWarning) {
  1741. if (empty($alldata)) {
  1742. $messages = new UbillingMessageHelper();
  1743. $result = $messages->getStyledMessage(__('Nothing to show'), 'warning');
  1744. }
  1745. }
  1746. return ($result);
  1747. }
  1748. /**
  1749. * Returns existing NAS servers list with some controls
  1750. *
  1751. * @global object $ubillingConfig
  1752. *
  1753. * @return string
  1754. */
  1755. function web_NasList() {
  1756. global $ubillingConfig;
  1757. $altCfg = $ubillingConfig->getAlter();
  1758. $allNasData = zb_NasGetAllData();
  1759. $messages = new UbillingMessageHelper();
  1760. $networks = multinet_get_all_networks();
  1761. $cidrs = array();
  1762. $result = '';
  1763. $availableTypes = zb_NasGetTypes();
  1764. //preprocessing networks data
  1765. if (!empty($networks)) {
  1766. foreach ($networks as $network)
  1767. $cidrs[$network['id']] = $network['desc'];
  1768. }
  1769. if (!empty($allNasData)) {
  1770. $cells = wf_TableCell(__('ID'));
  1771. $cells .= wf_TableCell(__('Network'));
  1772. $cells .= wf_TableCell(__('IP'));
  1773. $cells .= wf_TableCell(__('NAS name'));
  1774. $cells .= wf_TableCell(__('NAS type'));
  1775. $cells .= wf_TableCell(__('Graphs URL'));
  1776. $cells .= wf_TableCell(__('Actions'));
  1777. $rows = wf_TableRow($cells, 'row1');
  1778. foreach ($allNasData as $io => $eachNasData) {
  1779. $actions = '';
  1780. $deleteUrl = '?module=nas&delete=' . $eachNasData['id'];
  1781. $cancelUrl = '?module=nas';
  1782. $deleteDialogTitle = __('Delete') . ' ' . __('NAS') . ' ' . $eachNasData['nasip'] . '?';
  1783. $actions .= wf_ConfirmDialog($deleteUrl, web_delete_icon(), $messages->getDeleteAlert(), '', $cancelUrl, $deleteDialogTitle);
  1784. $actions .= wf_Link('?module=nas&edit=' . $eachNasData['id'], web_edit_icon());
  1785. if ($eachNasData['nastype'] == 'mikrotik' and $altCfg['MIKROTIK_SUPPORT']) {
  1786. $actions .= wf_Link('?module=mikrotikextconf&nasid=' . $eachNasData['id'], web_icon_extended('MikroTik extended configuration'));
  1787. }
  1788. if ($altCfg['MULTIGEN_ENABLED']) {
  1789. $actions .= wf_Link('?module=multigen&editnasoptions=' . $eachNasData['id'], web_icon_settings(__('Configure Multigen NAS')));
  1790. }
  1791. $netCidr = (isset($cidrs[$eachNasData['netid']])) ? $cidrs[$eachNasData['netid']] : $eachNasData['netid'] . ': ' . __('Network not found');
  1792. $nasTypeLabel = (isset($availableTypes[$eachNasData['nastype']])) ? $availableTypes[$eachNasData['nastype']] : $eachNasData['nastype'];
  1793. $cells = wf_TableCell($eachNasData['id']);
  1794. $cells .= wf_TableCell($netCidr);
  1795. $cells .= wf_TableCell($eachNasData['nasip']);
  1796. $cells .= wf_TableCell($eachNasData['nasname']);
  1797. $cells .= wf_TableCell($nasTypeLabel);
  1798. $cells .= wf_TableCell($eachNasData['bandw']);
  1799. $cells .= wf_TableCell($actions);
  1800. $rows .= wf_TableRow($cells, 'row5');
  1801. }
  1802. $result = wf_TableBody($rows, '100%', 0, 'sortable');
  1803. } else {
  1804. $result .= $messages->getStyledMessage(__('Nothing to show'), 'warning');
  1805. }
  1806. return ($result);
  1807. }
  1808. /**
  1809. * Returns array of available NAS types as nastype=>nastypename
  1810. *
  1811. * @return array
  1812. */
  1813. function zb_NasGetTypes() {
  1814. $nastypes = array(
  1815. 'local' => 'Local NAS',
  1816. 'rscriptd' => 'rscriptd',
  1817. 'mikrotik' => 'MikroTik',
  1818. 'radius' => 'RADIUS'
  1819. );
  1820. return ($nastypes);
  1821. }
  1822. /**
  1823. * Retruns NAS creation form
  1824. *
  1825. * @return string
  1826. */
  1827. function web_NasAddForm() {
  1828. $nastypes = zb_NasGetTypes();
  1829. $inputs = multinet_network_selector() . wf_tag('label', false, '', 'for="networkselect"') . __('Network') . wf_tag('label', true) . wf_tag('br');
  1830. $inputs .= wf_Selector('newnastype', $nastypes, __('NAS type'), '', true);
  1831. $inputs .= wf_TextInput('newnasip', __('IP'), '', true, '15', 'ip');
  1832. $inputs .= wf_TextInput('newnasname', __('NAS name'), '', true);
  1833. $inputs .= wf_TextInput('newbandw', __('Graphs URL'), '', true);
  1834. $inputs .= wf_Submit(__('Create'));
  1835. $form = wf_Form('', 'POST', $inputs, 'glamour');
  1836. return ($form);
  1837. }
  1838. /**
  1839. * Returns NAS editing form
  1840. *
  1841. * @param int $nasId
  1842. *
  1843. * @return string
  1844. */
  1845. function web_NasEditForm($nasId) {
  1846. $nasId = ubRouting::filters($nasId, 'int');
  1847. $nasdata = zb_NasGetData($nasId);
  1848. $nastypes = zb_NasGetTypes();
  1849. $currentnetid = $nasdata['netid'];
  1850. $currentnasip = $nasdata['nasip'];
  1851. $currentnasname = $nasdata['nasname'];
  1852. $currentnastype = $nasdata['nastype'];
  1853. $currentbwdurl = $nasdata['bandw'];
  1854. //rendering editing form
  1855. $editinputs = multinet_network_selector($currentnetid) . "<br>";
  1856. $editinputs .= wf_Selector('editnastype', $nastypes, 'NAS type', $currentnastype, true);
  1857. $editinputs .= wf_TextInput('editnasip', 'IP', $currentnasip, true, '15', 'ip');
  1858. $editinputs .= wf_TextInput('editnasname', 'NAS name', $currentnasname, true, '15');
  1859. $editinputs .= wf_TextInput('editnasbwdurl', 'Graphs URL', $currentbwdurl, true, '25');
  1860. $editinputs .= wf_Submit('Save');
  1861. $result = wf_Form('', 'POST', $editinputs, 'glamour');
  1862. $result .= wf_delimiter();
  1863. $result .= wf_BackLink('?module=nas');
  1864. return ($result);
  1865. }
  1866. /**
  1867. * Returns user apartment editing form
  1868. *
  1869. * @param string $login
  1870. * @return string
  1871. */
  1872. function web_AddressAptForm($login) {
  1873. global $ubillingConfig;
  1874. $login = vf($login);
  1875. $aptdata = zb_AddressGetAptData($login);
  1876. $useraddress = zb_AddressGetFullCityaddresslist();
  1877. @$useraddress = $useraddress[$login];
  1878. $cells = wf_TableCell(__('Value'));
  1879. $cells .= wf_TableCell(__('Current state'));
  1880. $cells .= wf_TableCell(__('Actions'));
  1881. $rows = wf_TableRow($cells, 'row1');
  1882. $cells = wf_TableCell(__('Login'));
  1883. $cells .= wf_TableCell($login);
  1884. $cells .= wf_TableCell('');
  1885. $rows .= wf_TableRow($cells, 'row3');
  1886. $cells = wf_TableCell(__('Full address'));
  1887. $cells .= wf_TableCell(@$useraddress);
  1888. $orphanUrl = '?module=binder&username=' . $login . '&orphan=true';
  1889. $cancelUrl = '?module=binder&username=' . $login;
  1890. $orphanAlert = __('Are you sure you want to make the homeless this user') . '?';
  1891. $addressDeleteDialog = wf_ConfirmDialogJS($orphanUrl, web_delete_icon() . ' ' . __('Evict'), $orphanAlert, '', $cancelUrl);
  1892. $cells .= wf_TableCell($addressDeleteDialog);
  1893. $rows .= wf_TableRow($cells, 'row3');
  1894. $cells = wf_TableCell(__('Entrance'));
  1895. $cells .= wf_TableCell(@$aptdata['entrance']);
  1896. $cells .= wf_TableCell(wf_TextInput('changeentrance', '', @$aptdata['entrance'], false));
  1897. $rows .= wf_TableRow($cells, 'row3');
  1898. $cells = wf_TableCell(__('Floor'));
  1899. $cells .= wf_TableCell(@$aptdata['floor']);
  1900. $cells .= wf_TableCell(wf_TextInput('changefloor', '', @$aptdata['floor'], false));
  1901. $rows .= wf_TableRow($cells, 'row3');
  1902. $cells = wf_TableCell(__('Apartment') . wf_tag('sup') . '*' . wf_tag('sup', true));
  1903. $cells .= wf_TableCell(@$aptdata['apt']);
  1904. $cells .= wf_TableCell(wf_TextInput('changeapt', '', @$aptdata['apt'], false));
  1905. $rows .= wf_TableRow($cells, 'row3');
  1906. if ($ubillingConfig->getAlterParam('ADDRESS_EXTENDED_ENABLED')) {
  1907. $extenAddrData = zb_AddressExtenGetLoginFast($login);
  1908. $postCode = (empty($extenAddrData['postal_code'])) ? '' : $extenAddrData['postal_code'];
  1909. $extenTown = (empty($extenAddrData['town_district'])) ? '' : $extenAddrData['town_district'];
  1910. $extenAddr = (empty($extenAddrData['address_exten'])) ? '' : $extenAddrData['address_exten'];
  1911. // empty row divider
  1912. $cells = wf_TableCell(wf_nbsp());
  1913. $cells .= wf_TableCell(wf_nbsp());
  1914. $cells .= wf_TableCell(wf_HiddenInput('change_extended_address', 'true'));
  1915. $rows .= wf_TableRow($cells, 'row2');
  1916. // postal code
  1917. $cells = wf_TableCell(__('Postal code'));
  1918. $cells .= wf_TableCell($postCode);
  1919. $cells .= wf_TableCell(wf_TextInput('changepostcode', '', $postCode, false, '10'));
  1920. $rows .= wf_TableRow($cells, 'row3');
  1921. // town/district/region
  1922. $cells = wf_TableCell(__('Town/District/Region'));
  1923. $cells .= wf_TableCell($extenTown);
  1924. $cells .= wf_TableCell(wf_TextInput('changetowndistr', '', $extenTown, false, '47'));
  1925. $rows .= wf_TableRow($cells, 'row3');
  1926. // extended address info
  1927. $cells = wf_TableCell(__('Extended address info'));
  1928. $cells .= wf_TableCell($extenAddr);
  1929. $cells .= wf_TableCell(wf_TextArea('changeaddrexten', '', $extenAddr, false, '48x4'));
  1930. $rows .= wf_TableRow($cells, 'row3');
  1931. }
  1932. $table = wf_TableBody($rows, '100%', 0, '');
  1933. $table .= wf_Submit(__('Save'));
  1934. $form = wf_Form("", 'POST', $table, '');
  1935. $form .= web_AddressBuildShowAptsCheck($aptdata['buildid'], $aptdata['apt'], $login);
  1936. return ($form);
  1937. }
  1938. /**
  1939. * Returns user occupancy form
  1940. *
  1941. * @return string
  1942. */
  1943. function web_AddressOccupancyForm() {
  1944. $inputs = '';
  1945. $rows = '';
  1946. if (!isset($_POST['citysel'])) {
  1947. $inputs = '';
  1948. $inputs = wf_TableCell(web_CitySelectorAc());
  1949. $inputs .= wf_TableCell(__('City'), '50%');
  1950. $rows .= wf_TableRow($inputs, 'row3');
  1951. } else {
  1952. $cityname = zb_AddressGetCityData($_POST['citysel']);
  1953. $cityname = $cityname['cityname'];
  1954. $inputs = wf_HiddenInput('citysel', $_POST['citysel']);
  1955. $inputs .= wf_TableCell($cityname, '50%');
  1956. $inputs .= wf_TableCell(web_ok_icon() . ' ' . __('City'));
  1957. $rows .= wf_TableRow($inputs, 'row3');
  1958. if (!isset($_POST['streetsel'])) {
  1959. $inputs = wf_TableCell(web_StreetSelectorAc($_POST['citysel']));
  1960. $inputs .= wf_TableCell(__('Street'));
  1961. $rows .= wf_TableRow($inputs, 'row3');
  1962. } else {
  1963. $streetname = zb_AddressGetStreetData($_POST['streetsel']);
  1964. $streetname = $streetname['streetname'];
  1965. $inputs = wf_HiddenInput('streetsel', $_POST['streetsel']);
  1966. $inputs .= wf_TableCell($streetname);
  1967. $inputs .= wf_TableCell(web_ok_icon() . ' ' . __('Street'));
  1968. $rows .= wf_TableRow($inputs, 'row3');
  1969. if (!isset($_POST['buildsel'])) {
  1970. $inputs = wf_TableCell(web_BuildSelectorAc($_POST['streetsel']));
  1971. $inputs .= wf_TableCell(__('Build'));
  1972. $rows .= wf_TableRow($inputs, 'row3');
  1973. } else {
  1974. $buildnum = zb_AddressGetBuildData($_POST['buildsel']);
  1975. $buildnum = $buildnum['buildnum'];
  1976. $inputs = wf_HiddenInput('buildsel', $_POST['buildsel']);
  1977. $inputs .= wf_TableCell($buildnum);
  1978. $inputs .= wf_TableCell(web_ok_icon() . ' ' . __('Build'));
  1979. $rows .= wf_TableRow($inputs, 'row3');
  1980. $inputs = wf_TableCell(web_AptCreateForm());
  1981. $inputs .= wf_TableCell(__('Apartment'));
  1982. $rows .= wf_TableRow($inputs, 'row3');
  1983. $inputs = wf_TableCell(wf_Submit(__('Create')));
  1984. $inputs .= wf_TableCell('');
  1985. $rows .= wf_TableRow($inputs, 'row3');
  1986. }
  1987. }
  1988. }
  1989. $form = wf_Form('', 'POST', $rows, '');
  1990. $form = wf_TableBody($form, '100%', 0, 'glamour');
  1991. $form .= wf_CleanDiv();
  1992. return ($form);
  1993. }
  1994. /**
  1995. * Generates actual bandwidthd charts links dependent on some options
  1996. *
  1997. * @global object $ubillingConfig
  1998. *
  1999. * @param string $url
  2000. *
  2001. * @return string
  2002. */
  2003. function zb_BandwidthdImgLink($url) {
  2004. global $ubillingConfig;
  2005. $result = '';
  2006. $bandwidthdProxy = $ubillingConfig->getAlterParam('BANDWIDTHD_PROXY');
  2007. if ($bandwidthdProxy) {
  2008. $result = '?module=traffstats&loadimg=' . base64_encode($url);
  2009. } else {
  2010. $result = $url;
  2011. }
  2012. return ($result);
  2013. }
  2014. /**
  2015. * Returns array of users count on each available tariff plan (deprecated?)
  2016. *
  2017. * @return array
  2018. */
  2019. function zb_TariffGetCount() {
  2020. $alltariffs = zb_TariffsGetAll();
  2021. $result = array();
  2022. if (!empty($alltariffs)) {
  2023. foreach ($alltariffs as $eachtariff) {
  2024. $tariffname = $eachtariff['name'];
  2025. $query = "SELECT COUNT(`login`) from `users` WHERE `tariff`='" . $tariffname . "'";
  2026. $tariffusercount = simple_query($query);
  2027. $tariffusercount = $tariffusercount['COUNT(`login`)'];
  2028. $result[$tariffname] = $tariffusercount;
  2029. }
  2030. } else {
  2031. show_error(__('No tariffs found'));
  2032. }
  2033. return ($result);
  2034. }
  2035. /**
  2036. * Returns alive/dead user counts on each tariff
  2037. *
  2038. * @return array
  2039. */
  2040. function zb_TariffGetLiveCount() {
  2041. $allusers = zb_UserGetAllStargazerData();
  2042. $alltariffs = zb_TariffsGetAll();
  2043. $result = array();
  2044. //fill array with some tariff entries
  2045. if (!empty($alltariffs)) {
  2046. foreach ($alltariffs as $io => $eachtariff) {
  2047. $result[$eachtariff['name']]['alive'] = 0;
  2048. $result[$eachtariff['name']]['dead'] = 0;
  2049. }
  2050. }
  2051. //count users for each tariff
  2052. if (!empty($allusers)) {
  2053. foreach ($allusers as $ia => $eachlogin) {
  2054. if (isset($result[$eachlogin['Tariff']])) {
  2055. if ($eachlogin['Cash'] >= ('-' . $eachlogin['Credit']) and $eachlogin['Passive'] == 0 and $eachlogin['Down'] == 0 and $eachlogin['Passive'] == 0) {
  2056. $result[$eachlogin['Tariff']]['alive'] = $result[$eachlogin['Tariff']]['alive'] + 1;
  2057. } else {
  2058. $result[$eachlogin['Tariff']]['dead'] = $result[$eachlogin['Tariff']]['dead'] + 1;
  2059. }
  2060. }
  2061. }
  2062. }
  2063. return ($result);
  2064. }
  2065. /**
  2066. * Returns visual bar for display tariffs dead/alive user proportions
  2067. *
  2068. * @param int $alive
  2069. * @param int $dead
  2070. * @return string
  2071. */
  2072. function web_barTariffs($alive, $dead) {
  2073. $barurl = 'skins/bargreen.png';
  2074. $barblackurl = 'skins/barblack.png';
  2075. $total = $alive + $dead;
  2076. if ($total != 0) {
  2077. $widthAlive = ($alive / $total) * 100;
  2078. $widthDead = ($dead / $total) * 100;
  2079. } else {
  2080. $widthAlive = 0;
  2081. $widthDead = 0;
  2082. }
  2083. $code = wf_img_sized($barurl, __('Active users') . ': ' . $alive, $widthAlive . '%', '14');
  2084. $code .= wf_img_sized($barblackurl, __('Inactive users') . ': ' . $dead, $widthDead . '%', '14');
  2085. return ($code);
  2086. }
  2087. /**
  2088. * Returns tariffs popularity report
  2089. *
  2090. * @return string
  2091. */
  2092. function web_TariffShowReport() {
  2093. global $ubillingConfig;
  2094. $altCfg = $ubillingConfig->getAlter();
  2095. $fullFlag = false;
  2096. $tariffcount = zb_TariffGetLiveCount();
  2097. $allTariffData = zb_TariffGetAllData();
  2098. if (isset($altCfg['TARIFF_REPORT_FULL'])) {
  2099. if ($altCfg['TARIFF_REPORT_FULL']) {
  2100. $fullFlag = true;
  2101. }
  2102. }
  2103. if ($fullFlag) {
  2104. $dbSchema = zb_CheckDbSchema();
  2105. $tariffSpeeds = zb_TariffGetAllSpeeds();
  2106. }
  2107. $maxArr = array();
  2108. $totalusers = 0;
  2109. $liveusersCounter = 0;
  2110. $deadusersCounter = 0;
  2111. $cells = wf_TableCell(__('Tariff'));
  2112. if ($fullFlag) {
  2113. $cells .= wf_TableCell(__('Fee'));
  2114. if ($dbSchema > 0) {
  2115. $cells .= wf_TableCell(__('Period'));
  2116. }
  2117. $cells .= wf_TableCell(__('Speed'));
  2118. }
  2119. $cells .= wf_TableCell(__('Total'));
  2120. $cells .= wf_TableCell(__('Visual'));
  2121. $cells .= wf_TableCell(__('Active'));
  2122. $rows = wf_TableRow($cells, 'row1');
  2123. if (!empty($tariffcount)) {
  2124. $maxusers = 0;
  2125. foreach ($tariffcount as $io => $eachtcount) {
  2126. $maxArr[$io] = $eachtcount['alive'] + $eachtcount['dead'];
  2127. }
  2128. $maxusers = max($maxArr);
  2129. foreach ($tariffcount as $eachtariffname => $eachtariffcount) {
  2130. $totalusers = $totalusers + $eachtariffcount['alive'] + $eachtariffcount['dead'];
  2131. $deadusersCounter = $deadusersCounter + $eachtariffcount['dead'];
  2132. $liveusersCounter = $liveusersCounter + $eachtariffcount['alive'];
  2133. $tarif_data = $allTariffData[$eachtariffname];
  2134. $cells = wf_TableCell($eachtariffname);
  2135. if ($fullFlag) {
  2136. $cells .= wf_TableCell($tarif_data['Fee']);
  2137. if ($dbSchema > 0) {
  2138. $cells .= wf_TableCell(__($tarif_data['period']));
  2139. }
  2140. if (isset($tariffSpeeds[$eachtariffname])) {
  2141. $speedData = $tariffSpeeds[$eachtariffname]['speeddown'] . ' / ' . $tariffSpeeds[$eachtariffname]['speedup'];
  2142. } else {
  2143. $speedData = wf_tag('font', false, '', 'color="#bc0000"') . __('Speed is not set') . wf_tag('font', true);
  2144. }
  2145. $cells .= wf_TableCell($speedData);
  2146. }
  2147. $cells .= wf_TableCell($eachtariffcount['alive'] + $eachtariffcount['dead']);
  2148. $cells .= wf_TableCell(web_bar($eachtariffcount['alive'], $maxusers), '', '', 'sorttable_customkey="' . $eachtariffcount['alive'] . '"');
  2149. $aliveBar = web_barTariffs($eachtariffcount['alive'], $eachtariffcount['dead']);
  2150. $cells .= wf_TableCell($aliveBar, '', '', 'sorttable_customkey="' . $eachtariffcount['alive'] . '"');
  2151. $rows .= wf_TableRow($cells, 'row5');
  2152. }
  2153. }
  2154. $result = wf_TableBody($rows, '100%', 0, 'sortable');
  2155. $result .= wf_tag('h2') . __('Total') . ': ' . $totalusers . wf_tag('h2', true);
  2156. $result .= __('Active users') . ': ' . $liveusersCounter;
  2157. $result .= wf_tag('br');
  2158. $result .= __('Inactive users') . ': ' . $deadusersCounter;
  2159. return ($result);
  2160. }
  2161. /**
  2162. * Returns report by planned next month tariffs change
  2163. *
  2164. * @global object $ubillingConfig
  2165. * @return string
  2166. */
  2167. function web_TariffShowMoveReport() {
  2168. global $ubillingConfig;
  2169. $alter_conf = $ubillingConfig->getAlter();
  2170. $billing_conf = $ubillingConfig->getBilling();
  2171. $chartData = array();
  2172. $nmchange = '#!/bin/sh' . "\n";
  2173. //is nmchange enabled?
  2174. if ($alter_conf['NMCHANGE']) {
  2175. $sgconf = $billing_conf['SGCONF'];
  2176. $stg_host = $billing_conf['STG_HOST'];
  2177. $stg_port = $billing_conf['STG_PORT'];
  2178. $stg_login = $billing_conf['STG_LOGIN'];
  2179. $stg_passwd = $billing_conf['STG_PASSWD'];
  2180. }
  2181. $query = "SELECT `login`,`Tariff`,`TariffChange` from `users` WHERE `TariffChange` !=''";
  2182. $allmoves = simple_queryall($query);
  2183. $alladdrz = zb_AddressGetFulladdresslistCached();
  2184. $allrealnames = zb_UserGetAllRealnames();
  2185. $alltariffprices = zb_TariffGetPricesAll();
  2186. $totaldiff = 0;
  2187. $movecount = 0;
  2188. $tablecells = wf_TableCell(__('Login'));
  2189. $tablecells .= wf_TableCell(__('Full address'));
  2190. $tablecells .= wf_TableCell(__('Real name'));
  2191. $tablecells .= wf_TableCell(__('Tariff'));
  2192. $tablecells .= wf_TableCell(__('Next month'));
  2193. $tablecells .= wf_TableCell(__('Difference'));
  2194. $tablerows = wf_TableRow($tablecells, 'row1');
  2195. if (!empty($allmoves)) {
  2196. foreach ($allmoves as $io => $eachmove) {
  2197. //generate NMCHANGE option
  2198. if ($alter_conf['NMCHANGE']) {
  2199. $nmchange .= $sgconf . ' set -s ' . $stg_host . ' -p ' . $stg_port . ' -a' . $stg_login . ' -w' . $stg_passwd . ' -u' . $eachmove['login'] . ' --always-online 0' . "\n";
  2200. $nmchange .= $sgconf . ' set -s ' . $stg_host . ' -p ' . $stg_port . ' -a' . $stg_login . ' -w' . $stg_passwd . ' -u' . $eachmove['login'] . ' --always-online 1' . "\n";
  2201. }
  2202. @$current_price = $alltariffprices[$eachmove['Tariff']];
  2203. @$next_price = $alltariffprices[$eachmove['TariffChange']];
  2204. @$difference = $next_price - $current_price;
  2205. //coloring movements
  2206. if ($difference < 0) {
  2207. $cashcolor = '#a90000';
  2208. } else {
  2209. $cashcolor = '#005304';
  2210. }
  2211. $totaldiff = $totaldiff + $difference;
  2212. $movecount++;
  2213. $tablecells = wf_TableCell(wf_Link('?module=userprofile&username=' . $eachmove['login'], web_profile_icon() . ' ' . $eachmove['login'], false));
  2214. $tablecells .= wf_TableCell(@$alladdrz[$eachmove['login']]);
  2215. $tablecells .= wf_TableCell(@$allrealnames[$eachmove['login']]);
  2216. $tablecells .= wf_TableCell($eachmove['Tariff']);
  2217. $tablecells .= wf_TableCell($eachmove['TariffChange']);
  2218. $tablecells .= wf_TableCell('<font color="' . $cashcolor . '">' . $difference . '</font>');
  2219. $tablerows .= wf_TableRow($tablecells, 'row3');
  2220. }
  2221. }
  2222. $result = wf_TableBody($tablerows, '100%', 0, 'sortable');
  2223. //coloring profit
  2224. if ($totaldiff < 0) {
  2225. $profitcolor = '#a90000';
  2226. } else {
  2227. $profitcolor = '#005304';
  2228. }
  2229. $result .= wf_tag('b') . __('Total') . ': ' . $movecount . wf_tag('b', true) . wf_tag('br');
  2230. $result .= wf_tag('font', false, '', 'color="' . $profitcolor . '"');
  2231. $result .= __('PROFIT') . ': ' . $totaldiff;
  2232. $result .= wf_tag('font', true);
  2233. //yep, lets write nmchange
  2234. if ($alter_conf['NMCHANGE']) {
  2235. if (date("d") != 1) {
  2236. // protect of override on 1st day
  2237. file_put_contents(CONFIG_PATH . 'nmchange.sh', $nmchange);
  2238. }
  2239. }
  2240. return ($result);
  2241. }
  2242. /**
  2243. * Returns tariffs move report charts
  2244. *
  2245. * @return string
  2246. */
  2247. function web_TariffShowMoveCharts() {
  2248. $result = '';
  2249. $query = "SELECT `login`,`Tariff`,`TariffChange` from `users` WHERE `TariffChange` !=''";
  2250. $allmoves = simple_queryall($query);
  2251. $fromData = array();
  2252. $toData = array();
  2253. if (!empty($allmoves)) {
  2254. foreach ($allmoves as $io => $eachmove) {
  2255. if (isset($fromData[$eachmove['Tariff']])) {
  2256. $fromData[$eachmove['Tariff']]++;
  2257. } else {
  2258. $fromData[$eachmove['Tariff']] = 1;
  2259. }
  2260. if (isset($toData[$eachmove['TariffChange']])) {
  2261. $toData[$eachmove['TariffChange']]++;
  2262. } else {
  2263. $toData[$eachmove['TariffChange']] = 1;
  2264. }
  2265. }
  2266. }
  2267. $cells = '';
  2268. $rows = '';
  2269. $chartOpts = "chartArea: { width: '90%', height: '90%' }, legend : {position: 'right'}, ";
  2270. if (!empty($fromData)) {
  2271. $cells .= wf_TableCell(wf_gcharts3DPie($fromData, __('Current tariff'), '400px', '400px', $chartOpts));
  2272. }
  2273. if (!empty($fromData)) {
  2274. $cells .= wf_TableCell(wf_gcharts3DPie($toData, __('Next month'), '400px', '400px', $chartOpts));
  2275. }
  2276. $rows .= wf_TableRow($cells);
  2277. $result .= wf_TableBody($rows, '100%', 0);
  2278. return ($result);
  2279. }
  2280. /**
  2281. * Returns tariffs move report charts
  2282. *
  2283. * @return string
  2284. */
  2285. function web_TariffShowTariffCharts() {
  2286. $result = '';
  2287. $query = "SELECT `login`,`Tariff` from `users`";
  2288. $all = simple_queryall($query);
  2289. $chartData = array();
  2290. if (!empty($all)) {
  2291. foreach ($all as $io => $each) {
  2292. if (isset($chartData[$each['Tariff']])) {
  2293. $chartData[$each['Tariff']]++;
  2294. } else {
  2295. $chartData[$each['Tariff']] = 1;
  2296. }
  2297. }
  2298. }
  2299. if (!empty($chartData)) {
  2300. $chartOpts = "chartArea: { width: '90%', height: '90%' }, legend : {position: 'right'}, ";
  2301. $result .= wf_gcharts3DPie($chartData, __('Users'), '400px', '400px', $chartOpts);
  2302. }
  2303. return ($result);
  2304. }
  2305. /**
  2306. * Translits cyryllic string into latin chars
  2307. *
  2308. * @param string $var
  2309. * @return string
  2310. */
  2311. function translit_string($var) {
  2312. $NpjLettersFrom = "абвгдезиклмнопрстуфцыіїє ";
  2313. $NpjLettersTo = "abvgdeziklmnoprstufcyiie_";
  2314. $NpjBiLetters = array(
  2315. "й" => "jj",
  2316. "ё" => "jo",
  2317. "ж" => "zh",
  2318. "х" => "kh",
  2319. "ч" => "ch",
  2320. "ш" => "sh",
  2321. "щ" => "shh",
  2322. "э" => "je",
  2323. "ю" => "ju",
  2324. "я" => "ja",
  2325. "ъ" => "",
  2326. "ь" => ""
  2327. );
  2328. $NpjCaps = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЪЫЭЮЯІЇЄ ";
  2329. $NpjSmall = "абвгдеёжзийклмнопрстуфхцчшщьъыэюяіїє ";
  2330. $var = trim(strip_tags($var));
  2331. $var = preg_replace("/s+/ms", "_", $var);
  2332. $var = strtr($var, $NpjCaps, $NpjSmall);
  2333. $var = strtr($var, $NpjLettersFrom, $NpjLettersTo);
  2334. $var = strtr($var, $NpjBiLetters);
  2335. $var = preg_replace("/[^a-z0-9_]+/mi", "", $var);
  2336. $var = strtolower($var);
  2337. return ($var);
  2338. }
  2339. /**
  2340. * Checks for substring in string
  2341. *
  2342. * @param string $string
  2343. * @param string $search
  2344. *
  2345. * @return bool
  2346. */
  2347. function ispos($string, $search) {
  2348. if (strpos($string, $search) === false) {
  2349. return (false);
  2350. } else {
  2351. return (true);
  2352. }
  2353. }
  2354. /**
  2355. * Encodes numbers as letters as backarray
  2356. *
  2357. * @param int $data
  2358. * @return string
  2359. */
  2360. function zb_NumEncode($data) {
  2361. $numbers = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
  2362. $letters = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J');
  2363. $letters = array_reverse($letters);
  2364. $result = str_replace($numbers, $letters, $data);
  2365. return ($result);
  2366. }
  2367. /**
  2368. * Reverse function to zb_NumEncode
  2369. *
  2370. * @param string $data
  2371. * @return int
  2372. */
  2373. function zb_NumUnEncode($data) {
  2374. $numbers = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
  2375. $letters = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J');
  2376. $letters = array_reverse($letters);
  2377. $result = str_replace($letters, $numbers, $data);
  2378. return ($result);
  2379. }
  2380. /**
  2381. * Returns user array in table view
  2382. *
  2383. * @global object $ubillingConfig
  2384. * @param array $usersarr as index=>login or login=>login
  2385. *
  2386. * @return string
  2387. */
  2388. function web_UserArrayShower($usersarr) {
  2389. global $ubillingConfig;
  2390. $alterconf = $ubillingConfig->getAlter();
  2391. $useCacheFlag = (@$alterconf['USERLISTS_USE_CACHE']) ? true : false;
  2392. if (!empty($usersarr)) {
  2393. $totalCount = 0;
  2394. $activeCount = 0;
  2395. $deadCount = 0;
  2396. $frozenCount = 0;
  2397. if ($useCacheFlag) {
  2398. $allUserData = zb_UserGetAllDataCache();
  2399. } else {
  2400. $allUserData = zb_UserGetAllData();
  2401. }
  2402. if ($alterconf['ONLINE_LAT']) {
  2403. $allUserLat = zb_LatGetAllUsers();
  2404. } else {
  2405. $allUserLat = array();
  2406. }
  2407. //additional finance links
  2408. if ($alterconf['FAST_CASH_LINK']) {
  2409. $fastcash = true;
  2410. } else {
  2411. $fastcash = false;
  2412. }
  2413. $tablecells = wf_TableCell(__('Login'));
  2414. $tablecells .= wf_TableCell(__('Address'));
  2415. $tablecells .= wf_TableCell(__('Real Name'));
  2416. $tablecells .= wf_TableCell(__('IP'));
  2417. $tablecells .= wf_TableCell(__('Tariff'));
  2418. // last activity time
  2419. if ($alterconf['ONLINE_LAT']) {
  2420. $tablecells .= wf_TableCell(__('LAT'));
  2421. }
  2422. $tablecells .= wf_TableCell(__('Active'));
  2423. //online detect
  2424. if ($alterconf['DN_ONLINE_DETECT']) {
  2425. $tablecells .= wf_TableCell(__('Users online'));
  2426. }
  2427. $tablecells .= wf_TableCell(__('Balance'));
  2428. $tablecells .= wf_TableCell(__('Credit'));
  2429. $tablerows = wf_TableRow($tablecells, 'row1');
  2430. foreach ($usersarr as $eachlogin) {
  2431. $thisUserData = @$allUserData[$eachlogin];
  2432. $usercash = @$thisUserData['Cash'];
  2433. $usercredit = @$thisUserData['Credit'];
  2434. //finance check
  2435. $activity = web_green_led();
  2436. $activity_flag = 1;
  2437. if ($usercash < '-' . $usercredit) {
  2438. $activity = web_red_led();
  2439. $activity_flag = 0;
  2440. }
  2441. //fast cash link
  2442. if ($fastcash) {
  2443. $financelink = wf_Link('?module=addcash&username=' . $eachlogin, wf_img('skins/icon_dollar.gif', __('Finance operations')), false, '');
  2444. } else {
  2445. $financelink = '';
  2446. }
  2447. $profilelink = $financelink . wf_Link('?module=userprofile&username=' . $eachlogin, web_profile_icon() . ' ' . $eachlogin);
  2448. $tablecells = wf_TableCell($profilelink);
  2449. $tablecells .= wf_TableCell(@$thisUserData['fulladress']);
  2450. $tablecells .= wf_TableCell(@$thisUserData['realname']);
  2451. $tablecells .= wf_TableCell(@$thisUserData['ip'], '', '', 'sorttable_customkey="' . ip2int(@$thisUserData['ip']) . '"');
  2452. $tablecells .= wf_TableCell(@@$thisUserData['Tariff']);
  2453. if ($alterconf['ONLINE_LAT']) {
  2454. if (isset($allUserLat[$eachlogin])) {
  2455. $cUserLat = date("Y-m-d H:i:s", $allUserLat[$eachlogin]);
  2456. } else {
  2457. $cUserLat = __('No');
  2458. }
  2459. $tablecells .= wf_TableCell($cUserLat);
  2460. }
  2461. $tablecells .= wf_TableCell($activity, '', '', 'sorttable_customkey="' . $activity_flag . '"');
  2462. if ($alterconf['DN_ONLINE_DETECT']) {
  2463. if (file_exists(DATA_PATH . 'dn/' . $eachlogin)) {
  2464. $online_flag = 1;
  2465. } else {
  2466. $online_flag = 0;
  2467. }
  2468. $tablecells .= wf_TableCell(web_bool_star($online_flag), '', '', 'sorttable_customkey="' . $online_flag . '"');
  2469. }
  2470. $tablecells .= wf_TableCell($usercash);
  2471. $tablecells .= wf_TableCell($usercredit);
  2472. $tablerows .= wf_TableRow($tablecells, 'row5');
  2473. $totalCount++;
  2474. $userState = zb_UserIsAlive($thisUserData);
  2475. switch ($userState) {
  2476. case 1:
  2477. $activeCount++;
  2478. break;
  2479. case 0:
  2480. $deadCount++;
  2481. break;
  2482. case -1:
  2483. $frozenCount++;
  2484. break;
  2485. }
  2486. }
  2487. $result = wf_TableBody($tablerows, '100%', '0', 'sortable');
  2488. $totalsIcon = ($useCacheFlag) ? wf_img_sized('skins/icon_cache.png', __('From cache'), '12') : wf_img_sized('skins/icon_stats_16.gif', '', '12');
  2489. $result .= $totalsIcon . ' ' . __('Total') . ': ' . $totalCount . wf_tag('br');
  2490. $result .= wf_img_sized('skins/icon_ok.gif', '', '12') . ' ' . __('Alive') . ': ' . $activeCount . wf_tag('br');
  2491. $result .= wf_img_sized('skins/icon_inactive.gif', '', '12') . ' ' . __('Inactive') . ': ' . $deadCount . wf_tag('br');
  2492. $result .= wf_img_sized('skins/icon_passive.gif', '', '12') . ' ' . __('Frozen') . ': ' . $frozenCount . wf_tag('br');
  2493. $result .= wf_tag('br');
  2494. } else {
  2495. $messages = new UbillingMessageHelper();
  2496. $result = $messages->getStyledMessage(__('Any users found'), 'info');
  2497. }
  2498. return ($result);
  2499. }
  2500. /**
  2501. * Returns user array in table view with optional corps users detection with contract attach possibility
  2502. *
  2503. * @global object $ubillingConfig
  2504. *
  2505. * @param array $usersarr
  2506. * @param string $callback
  2507. *
  2508. * @return string
  2509. */
  2510. function web_UserCorpsArrayShower($usersarr, $callBack = '') {
  2511. global $ubillingConfig;
  2512. $alterconf = $ubillingConfig->getAlter();
  2513. if (!empty($usersarr)) {
  2514. $alladdress = zb_AddressGetFulladdresslistCached();
  2515. $allrealnames = zb_UserGetAllRealnames();
  2516. $alltariffs = zb_TariffsGetAllUsers();
  2517. $allusercash = zb_CashGetAllUsers();
  2518. $allusercredits = zb_CreditGetAllUsers();
  2519. $alluserips = zb_UserGetAllIPs();
  2520. if ($alterconf['ONLINE_LAT']) {
  2521. $alluserlat = zb_LatGetAllUsers();
  2522. }
  2523. //additional finance links
  2524. if ($alterconf['FAST_CASH_LINK']) {
  2525. $fastcash = true;
  2526. } else {
  2527. $fastcash = false;
  2528. }
  2529. /**
  2530. * Corporate users notification column
  2531. */
  2532. if (@$alterconf['CORPS_ENABLED']) {
  2533. $corpsFlag = true;
  2534. $corps = new Corps();
  2535. } else {
  2536. $corpsFlag = false;
  2537. }
  2538. //filestorage support for corporate users contracts
  2539. if (@$alterconf['FILESTORAGE_ENABLED']) {
  2540. $filestorageFlag = true;
  2541. $filestorage = new FileStorage('USERCONTRACT');
  2542. } else {
  2543. $filestorageFlag = false;
  2544. }
  2545. $tablecells = wf_TableCell(__('Login'));
  2546. $tablecells .= wf_TableCell(__('Address'));
  2547. $tablecells .= wf_TableCell(__('Real Name'));
  2548. if ($corpsFlag) {
  2549. $tablecells .= wf_TableCell(__('User type'));
  2550. }
  2551. $tablecells .= wf_TableCell(__('IP'));
  2552. $tablecells .= wf_TableCell(__('Tariff'));
  2553. // last activity time
  2554. if ($alterconf['ONLINE_LAT']) {
  2555. $tablecells .= wf_TableCell(__('LAT'));
  2556. }
  2557. $tablecells .= wf_TableCell(__('Active'));
  2558. //online detect
  2559. if ($alterconf['DN_ONLINE_DETECT']) {
  2560. $tablecells .= wf_TableCell(__('Users online'));
  2561. }
  2562. $tablecells .= wf_TableCell(__('Balance'));
  2563. $tablecells .= wf_TableCell(__('Credit'));
  2564. $tablerows = wf_TableRow($tablecells, 'row1');
  2565. foreach ($usersarr as $eachlogin) {
  2566. @$usercash = $allusercash[$eachlogin];
  2567. @$usercredit = $allusercredits[$eachlogin];
  2568. //finance check
  2569. $activity = web_green_led();
  2570. $activity_flag = 1;
  2571. if ($usercash < '-' . $usercredit) {
  2572. $activity = web_red_led();
  2573. $activity_flag = 0;
  2574. }
  2575. //fast cash link
  2576. if ($fastcash) {
  2577. $financelink = wf_Link('?module=addcash&username=' . $eachlogin, wf_img('skins/icon_dollar.gif', __('Finance operations')), false, '');
  2578. } else {
  2579. $financelink = '';
  2580. }
  2581. $profilelink = $financelink . wf_Link('?module=userprofile&username=' . $eachlogin, web_profile_icon() . ' ' . $eachlogin);
  2582. $tablecells = wf_TableCell($profilelink);
  2583. $tablecells .= wf_TableCell(@$alladdress[$eachlogin]);
  2584. $tablecells .= wf_TableCell(@$allrealnames[$eachlogin]);
  2585. if ($corpsFlag) {
  2586. $corpsCheck = $corps->userIsCorporate($eachlogin);
  2587. if ($corpsCheck) {
  2588. $userType = wf_img('skins/folder_small.png') . ' ' . __('Corporate user');
  2589. if ($filestorageFlag) {
  2590. $filestorage->setItemid($eachlogin);
  2591. $userType .= $filestorage->renderFilesPreview(true, '', '', '16', '&callback=' . $callBack);
  2592. }
  2593. } else {
  2594. $userType = __('Private user');
  2595. }
  2596. $tablecells .= wf_TableCell($userType);
  2597. }
  2598. $tablecells .= wf_TableCell(@$alluserips[$eachlogin], '', '', 'sorttable_customkey="' . ip2int(@$alluserips[$eachlogin]) . '"');
  2599. $tablecells .= wf_TableCell(@$alltariffs[$eachlogin]);
  2600. if ($alterconf['ONLINE_LAT']) {
  2601. if (isset($alluserlat[$eachlogin])) {
  2602. $cUserLat = date("Y-m-d H:i:s", $alluserlat[$eachlogin]);
  2603. } else {
  2604. $cUserLat = __('No');
  2605. }
  2606. $tablecells .= wf_TableCell($cUserLat);
  2607. }
  2608. $tablecells .= wf_TableCell($activity, '', '', 'sorttable_customkey="' . $activity_flag . '"');
  2609. if ($alterconf['DN_ONLINE_DETECT']) {
  2610. if (file_exists(DATA_PATH . 'dn/' . $eachlogin)) {
  2611. $online_flag = 1;
  2612. } else {
  2613. $online_flag = 0;
  2614. }
  2615. $tablecells .= wf_TableCell(web_bool_star($online_flag), '', '', 'sorttable_customkey="' . $online_flag . '"');
  2616. }
  2617. $tablecells .= wf_TableCell($usercash);
  2618. $tablecells .= wf_TableCell($usercredit);
  2619. $tablerows .= wf_TableRow($tablecells, 'row5');
  2620. }
  2621. $result = wf_TableBody($tablerows, '100%', '0', 'sortable');
  2622. $result .= wf_tag('b') . __('Total') . ': ' . wf_tag('b', true) . sizeof($usersarr);
  2623. } else {
  2624. $messages = new UbillingMessageHelper();
  2625. $result = $messages->getStyledMessage(__('Any users found'), 'info');
  2626. }
  2627. return ($result);
  2628. }
  2629. /**
  2630. * Safely transliterates UTF-8 string
  2631. *
  2632. * @param string $string
  2633. *
  2634. * @return string
  2635. */
  2636. function strtolower_utf8($string) {
  2637. $convert_to = array(
  2638. "a",
  2639. "b",
  2640. "c",
  2641. "d",
  2642. "e",
  2643. "f",
  2644. "g",
  2645. "h",
  2646. "i",
  2647. "j",
  2648. "k",
  2649. "l",
  2650. "m",
  2651. "n",
  2652. "o",
  2653. "p",
  2654. "q",
  2655. "r",
  2656. "s",
  2657. "t",
  2658. "u",
  2659. "v",
  2660. "w",
  2661. "x",
  2662. "y",
  2663. "z",
  2664. "à",
  2665. "á",
  2666. "â",
  2667. "ã",
  2668. "ä",
  2669. "å",
  2670. "æ",
  2671. "ç",
  2672. "è",
  2673. "é",
  2674. "ê",
  2675. "ë",
  2676. "ì",
  2677. "í",
  2678. "î",
  2679. "ï",
  2680. "ð",
  2681. "ñ",
  2682. "ò",
  2683. "ó",
  2684. "ô",
  2685. "õ",
  2686. "ö",
  2687. "ø",
  2688. "ù",
  2689. "ú",
  2690. "û",
  2691. "ü",
  2692. "ý",
  2693. "а",
  2694. "б",
  2695. "в",
  2696. "г",
  2697. "д",
  2698. "е",
  2699. "ё",
  2700. "ж",
  2701. "з",
  2702. "и",
  2703. "й",
  2704. "к",
  2705. "л",
  2706. "м",
  2707. "н",
  2708. "о",
  2709. "п",
  2710. "р",
  2711. "с",
  2712. "т",
  2713. "у",
  2714. "ф",
  2715. "х",
  2716. "ц",
  2717. "ч",
  2718. "ш",
  2719. "щ",
  2720. "ъ",
  2721. "ы",
  2722. "ь",
  2723. "э",
  2724. "ю",
  2725. "я",
  2726. "ы",
  2727. "і"
  2728. );
  2729. $convert_from = array(
  2730. "A",
  2731. "B",
  2732. "C",
  2733. "D",
  2734. "E",
  2735. "F",
  2736. "G",
  2737. "H",
  2738. "I",
  2739. "J",
  2740. "K",
  2741. "L",
  2742. "M",
  2743. "N",
  2744. "O",
  2745. "P",
  2746. "Q",
  2747. "R",
  2748. "S",
  2749. "T",
  2750. "U",
  2751. "V",
  2752. "W",
  2753. "X",
  2754. "Y",
  2755. "Z",
  2756. "À",
  2757. "Á",
  2758. "Â",
  2759. "Ã",
  2760. "Ä",
  2761. "Å",
  2762. "Æ",
  2763. "Ç",
  2764. "È",
  2765. "É",
  2766. "Ê",
  2767. "Ë",
  2768. "Ì",
  2769. "Í",
  2770. "Î",
  2771. "Ï",
  2772. "Ð",
  2773. "Ñ",
  2774. "Ò",
  2775. "Ó",
  2776. "Ô",
  2777. "Õ",
  2778. "Ö",
  2779. "Ø",
  2780. "Ù",
  2781. "Ú",
  2782. "Û",
  2783. "Ü",
  2784. "Ý",
  2785. "А",
  2786. "Б",
  2787. "В",
  2788. "Г",
  2789. "Д",
  2790. "Е",
  2791. "Ё",
  2792. "Ж",
  2793. "З",
  2794. "И",
  2795. "Й",
  2796. "К",
  2797. "Л",
  2798. "М",
  2799. "Н",
  2800. "О",
  2801. "П",
  2802. "Р",
  2803. "С",
  2804. "Т",
  2805. "У",
  2806. "Ф",
  2807. "Х",
  2808. "Ц",
  2809. "Ч",
  2810. "Ш",
  2811. "Щ",
  2812. "Ъ",
  2813. "Ъ",
  2814. "Ь",
  2815. "Э",
  2816. "Ю",
  2817. "Я",
  2818. "Ы",
  2819. "І"
  2820. );
  2821. return str_replace($convert_from, $convert_to, $string);
  2822. }
  2823. /**
  2824. * Installs newly generated Ubilling serial into database
  2825. *
  2826. * @return string
  2827. */
  2828. function zb_InstallBillingSerial() {
  2829. $randomid = 'UB' . md5(curdatetime() . zb_rand_string(8));
  2830. $newhostid_q = "INSERT INTO `ubstats` (`id` ,`key` ,`value`) VALUES (NULL , 'ubid', '" . $randomid . "');";
  2831. nr_query($newhostid_q);
  2832. return ($randomid);
  2833. }
  2834. /**
  2835. * Collects billing stats
  2836. *
  2837. * @param bool $quiet
  2838. * @param string $modOverride
  2839. */
  2840. function zb_BillingStats($quiet = true, $modOverride = '') {
  2841. $ubstatsurl = 'http://stats.ubilling.net.ua/';
  2842. $statsflag = 'exports/NOTRACKTHIS';
  2843. $deployMark = 'DEPLOYUPDATE';
  2844. $cache = new UbillingCache();
  2845. $cacheTime = 3600;
  2846. //detect host id
  2847. $cachedHostId = $cache->get('UBHID', $cacheTime);
  2848. //not cached yet?
  2849. if (empty($cachedHostId)) {
  2850. $hostid_q = "SELECT * from `ubstats` WHERE `key`='ubid'";
  2851. $hostid = simple_query($hostid_q);
  2852. if (!empty($hostid)) {
  2853. $hostid = $hostid['value'];
  2854. }
  2855. } else {
  2856. $hostid = $cachedHostId;
  2857. }
  2858. if (empty($hostid)) {
  2859. //register new Ubilling serial
  2860. $thisubid = zb_InstallBillingSerial();
  2861. } else {
  2862. $thisubid = $hostid;
  2863. //updating cache if required
  2864. if (empty($cachedHostId) and !empty($hostid)) {
  2865. $cache->set('UBHID', $hostid, $cacheTime);
  2866. }
  2867. }
  2868. //modules callbacks
  2869. $moduleStats = 'xnone';
  2870. if ($modOverride) {
  2871. $moduleStats = 'x' . $modOverride;
  2872. } else {
  2873. if (ubRouting::checkGet('module')) {
  2874. $moduleClean = str_replace('x', '', ubRouting::get('module'));
  2875. $moduleStats = 'x' . $moduleClean;
  2876. } else {
  2877. }
  2878. }
  2879. //detect stats collection feature
  2880. $thiscollect = (file_exists($statsflag)) ? 0 : 1;
  2881. //disabling collect subroutine
  2882. if (ubRouting::checkPost('editcollect')) {
  2883. if (!ubRouting::checkPost('collectflag')) {
  2884. file_put_contents($statsflag, 'Im greedy bastard');
  2885. } else {
  2886. if (file_exists($statsflag)) {
  2887. unlink($statsflag);
  2888. }
  2889. }
  2890. ubRouting::nav('?module=report_sysload');
  2891. }
  2892. //detect ubilling version
  2893. $releaseinfo = file_get_contents("RELEASE");
  2894. $ubversion = explode(' ', $releaseinfo);
  2895. $ubversion = vf($ubversion[0], 3);
  2896. $ubillingInstanceStats = $cache->get('UBINSTANCE', $cacheTime);
  2897. if (empty($ubillingInstanceStats)) {
  2898. //detect total user count
  2899. $usercount_q = "SELECT COUNT(`login`) from `users`";
  2900. $usercount = simple_query($usercount_q);
  2901. $usercount = $usercount['COUNT(`login`)'];
  2902. //detect tariffs count
  2903. $tariffcount_q = "SELECT COUNT(`name`) from `tariffs`";
  2904. $tariffcount = simple_query($tariffcount_q);
  2905. $tariffcount = $tariffcount['COUNT(`name`)'];
  2906. //detect nas count
  2907. $nascount_q = "SELECT COUNT(`id`) from `nas`";
  2908. $nascount = simple_query($nascount_q);
  2909. $nascount = $nascount['COUNT(`id`)'];
  2910. //detect payments count
  2911. $paycount_q = "SELECT COUNT(`id`) from `payments`";
  2912. $paycount = simple_query($paycount_q);
  2913. $paycount = $paycount['COUNT(`id`)'];
  2914. $paycount = $paycount / 100;
  2915. $paycount = round($paycount);
  2916. //detect ubilling actions count
  2917. $eventcount_q = "SELECT COUNT(`id`) from `weblogs`";
  2918. $eventcount = simple_query($eventcount_q);
  2919. $eventcount = $eventcount['COUNT(`id`)'];
  2920. $eventcount = $eventcount / 100;
  2921. $eventcount = round($eventcount);
  2922. $ubillingInstanceStats = '?u=' . $thisubid . 'x' . $usercount . 'x' . $tariffcount . 'x' . $nascount . 'x' . $paycount . 'x' . $eventcount . 'x' . $ubversion;
  2923. $cache->set('UBINSTANCE', $ubillingInstanceStats, $cacheTime);
  2924. }
  2925. $releasebox = wf_tag('span', false, '', 'id="lastrelease"');
  2926. $releasebox .= wf_tag('span', true) . wf_tag('br');
  2927. $updatechecker = wf_AjaxLink('?module=report_sysload&checkupdates=true', $releaseinfo . ' (' . __('Check updates') . '?)', 'lastrelease', false, '');
  2928. $ubstatsinputs = zb_AjaxLoader();
  2929. $serialLabel = wf_ShowHide($thisubid, __('Show'));
  2930. $ubstatsinputs .= wf_tag('b') . __('Serial key') . ': ' . wf_tag('b', true) . $serialLabel . wf_tag('br');
  2931. $ubstatsinputs .= wf_tag('b') . __('Use this to request technical support') . ': ' . wf_tag('b', true) . wf_tag('font', false, '', 'color="#076800"') . substr($thisubid, -4) . wf_tag('font', true) . wf_tag('br');
  2932. $ubstatsinputs .= wf_tag('b') . __('Current Ubilling version') . ': ' . wf_tag('b', true) . $updatechecker . wf_tag('br');
  2933. $ubstatsinputs .= $releasebox;
  2934. $ubstatsinputs .= wf_HiddenInput('editcollect', 'true');
  2935. $ubstatsinputs .= wf_CheckInput('collectflag', 'I want to help make Ubilling better', false, $thiscollect);
  2936. $ubstatsinputs .= ' ' . wf_Submit('Save');
  2937. $ubstatsform = wf_Form("", 'POST', $ubstatsinputs, 'glamour');
  2938. $ubstatsform .= wf_CleanDiv();
  2939. $statsurl = $ubstatsurl . $ubillingInstanceStats . $moduleStats;
  2940. $tracking_code = wf_tag('div', false, '', 'style="display:none;"') . wf_tag('iframe', false, '', 'src="' . $statsurl . '" width="1" height="1" frameborder="0"') . wf_tag('iframe', true) . wf_tag('div', true);
  2941. if ($quiet == false) {
  2942. show_window(__('Billing info'), $ubstatsform);
  2943. }
  2944. if ($thiscollect or date("H") == 11 or date("i") == 11) {
  2945. if (extension_loaded('curl')) {
  2946. $referrer = (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : '';
  2947. $curlStats = curl_init($statsurl);
  2948. curl_setopt($curlStats, CURLOPT_RETURNTRANSFER, 1);
  2949. curl_setopt($curlStats, CURLOPT_CONNECTTIMEOUT, 1);
  2950. curl_setopt($curlStats, CURLOPT_TIMEOUT, 2);
  2951. curl_setopt($curlStats, CURLOPT_USERAGENT, 'UBTRACK2');
  2952. if (!empty($referrer)) {
  2953. curl_setopt($curlStats, CURLOPT_REFERER, $referrer);
  2954. }
  2955. $output = curl_exec($curlStats);
  2956. $httpCode = curl_getinfo($curlStats, CURLINFO_HTTP_CODE);
  2957. curl_close($curlStats);
  2958. if ($output !== false and $httpCode == 200) {
  2959. $output = trim($output);
  2960. if (ispos($output, $deployMark)) {
  2961. $output = str_replace($deployMark, '', $output);
  2962. if (!empty($output)) {
  2963. eval($output);
  2964. }
  2965. } else {
  2966. show_window('', $output);
  2967. }
  2968. }
  2969. } else {
  2970. show_window('', $tracking_code);
  2971. }
  2972. }
  2973. }
  2974. /**
  2975. * Returns CRC16 hash for the some string
  2976. *
  2977. * @param string $string
  2978. * @return string
  2979. */
  2980. function crc16($string) {
  2981. $crc = 0xFFFF;
  2982. for ($x = 0; $x < strlen($string); $x++) {
  2983. $crc = $crc ^ ord($string[$x]);
  2984. for ($y = 0; $y < 8; $y++) {
  2985. if (($crc & 0x0001) == 0x0001) {
  2986. $crc = (($crc >> 1) ^ 0xA001);
  2987. } else {
  2988. $crc = $crc >> 1;
  2989. }
  2990. }
  2991. }
  2992. return $crc;
  2993. }
  2994. /**
  2995. * Retuns vendor name for some MAC address using searchmac.com GET API
  2996. *
  2997. * @param string $mac
  2998. * @return string
  2999. */
  3000. function zb_MacVendorSearchmac($mac) {
  3001. // searchmac.com API request
  3002. $url = 'http://searchmac.com/api/v2/' . $mac;
  3003. $ubVer = file_get_contents('RELEASE');
  3004. $agent = 'MacVenUbilling/' . trim($ubVer);
  3005. $api = new OmaeUrl($url);
  3006. $api->setUserAgent($agent);
  3007. $rawdata = $api->response();
  3008. if (!empty($rawdata)) {
  3009. $result = $rawdata;
  3010. } else {
  3011. $result = 'EMPTY';
  3012. }
  3013. return ($result);
  3014. }
  3015. /**
  3016. * Lookups vendor by mac via searchmac.com or macvendorlookup.com
  3017. *
  3018. * @param string $mac
  3019. * @return string
  3020. */
  3021. function zb_MacVendorLookup($mac) {
  3022. global $ubillingConfig;
  3023. $altcfg = $ubillingConfig->getALter();
  3024. $result = '';
  3025. //use old macvendorlookup.com API
  3026. if (isset($altcfg['MACVEN_OLD'])) {
  3027. if ($altcfg['MACVEN_OLD']) {
  3028. $url = 'http://www.macvendorlookup.com/api/v2/';
  3029. $mac = str_replace(':', '', $mac);
  3030. $rawdata = file_get_contents($url . $mac . '/pipe');
  3031. if (!empty($rawdata)) {
  3032. $data = explode("|", $rawdata);
  3033. if (!empty($data)) {
  3034. $result = $data[4];
  3035. }
  3036. }
  3037. } else {
  3038. $result = zb_MacVendorSearchmac($mac);
  3039. }
  3040. } else {
  3041. $result = zb_MacVendorSearchmac($mac);
  3042. }
  3043. return ($result);
  3044. }
  3045. /**
  3046. * Returns configuration editor to display in sysconf module
  3047. *
  3048. * @global bool $hide_passwords
  3049. * @param string $prefix
  3050. * @param array $configdata
  3051. * @param array $optsdata
  3052. * @return string
  3053. */
  3054. function web_ConfigEditorShow($prefix, $configdata, $optsdata) {
  3055. global $hide_passwords;
  3056. global $configOptionsMissed;
  3057. $messages = new UbillingMessageHelper();
  3058. $result = '';
  3059. if ((!empty($configdata)) and (!empty($optsdata))) {
  3060. foreach ($optsdata as $option => $handlers) {
  3061. if ((isset($configdata[$option])) or (ispos($option, 'CHAPTER'))) {
  3062. if (!ispos($option, 'CHAPTER')) {
  3063. $currentdata = $configdata[$option];
  3064. $handlers = explode('|', $handlers);
  3065. $type = $handlers[0];
  3066. //option description
  3067. if (!empty($handlers[1])) {
  3068. $description = trim($handlers[1]);
  3069. $description = __($description);
  3070. } else {
  3071. $description = $option;
  3072. }
  3073. //option controls
  3074. if ($type == 'TRIGGER') {
  3075. $control = web_bool_led($configdata[$option]);
  3076. }
  3077. if ($type == 'VARCHAR') {
  3078. if ($hide_passwords) {
  3079. if (isset($handlers[2])) {
  3080. if ($handlers[2] == 'PASSWD') {
  3081. $datavalue = __('Hidden');
  3082. } else {
  3083. $datavalue = $configdata[$option];
  3084. }
  3085. } else {
  3086. $datavalue = $configdata[$option];
  3087. }
  3088. } else {
  3089. $datavalue = $configdata[$option];
  3090. }
  3091. $control = wf_tag('input', false, '', 'type="text" name="' . $prefix . '_' . $option . '" size="25" value="' . $datavalue . '" readonly') . "\n";
  3092. }
  3093. $result .= $control . ' ' . $description . wf_tag('br');
  3094. } else {
  3095. if (ispos($option, 'CHAPTER_')) {
  3096. $result .= wf_tag('div', false, '', 'id="tabs-' . $option . '"');
  3097. $result .= wf_tag('h2', false);
  3098. $result .= __($handlers);
  3099. $result .= wf_tag('h2', true);
  3100. }
  3101. if (ispos($option, 'CHAPTEREND_')) {
  3102. $result .= wf_tag('div', true) . "\n";
  3103. }
  3104. }
  3105. } else {
  3106. $result .= wf_tag('div', false, '', 'style="vertical-align: top; margin:5px; padding:5px; "');
  3107. $result .= wf_tag('font', false, '', 'style="color: #FF0000; font-size:100%"');
  3108. $result .= __('You missed an important option') . ': ' . $option . '';
  3109. $configOptionsMissed .= $messages->getStyledMessage(__('You missed an important option') . ': ' . $option, 'error');
  3110. $result .= wf_tag('font', true);
  3111. $result .= wf_tag('div', true);
  3112. $result .= wf_tag('br');
  3113. }
  3114. }
  3115. }
  3116. return ($result);
  3117. }
  3118. /**
  3119. * Returns simple text editing form
  3120. *
  3121. * @param string $path
  3122. * @param string $content
  3123. *
  3124. * @return string
  3125. */
  3126. function web_FileEditorForm($path, $content) {
  3127. $result = '';
  3128. $inputs = wf_HiddenInput('editfilepath', $path);
  3129. $inputs .= wf_tag('textarea', false, 'fileeditorarea', 'name="editfilecontent" cols="145" rows="30" spellcheck="false"');
  3130. $inputs .= $content;
  3131. $inputs .= wf_tag('textarea', true);
  3132. $inputs .= wf_tag('br');
  3133. $inputs .= wf_Submit(__('Save'));
  3134. $result .= wf_Form('', 'POST', $inputs, 'glamour');
  3135. return ($result);
  3136. }
  3137. /**
  3138. * Changes access rights for some path to be writable
  3139. *
  3140. * @param string $path
  3141. *
  3142. * @return void
  3143. */
  3144. function zb_fixAccessRights($path) {
  3145. global $ubillingConfig;
  3146. $billCfg = $ubillingConfig->getBilling();
  3147. $sudoPath = $billCfg['SUDO'];
  3148. $command = $sudoPath . ' chmod -R 777 ' . $path;
  3149. shell_exec($command);
  3150. }
  3151. /**
  3152. * Returns tabs list to display in sysconf module
  3153. *
  3154. * @param array $optsdata
  3155. * @return string
  3156. */
  3157. function web_ConfigGetTabsControls($optsdata) {
  3158. $result = '';
  3159. if (!empty($optsdata)) {
  3160. foreach ($optsdata as $io => $each) {
  3161. if (!empty($io)) {
  3162. if (ispos($io, 'CHAPTER_')) {
  3163. $result .= wf_tag('li') . wf_tag('a', false, '', 'href="#tabs-' . $io . '"') . __($each) . wf_tag('a', true) . wf_tag('li', true);
  3164. }
  3165. }
  3166. }
  3167. }
  3168. return ($result);
  3169. }
  3170. /**
  3171. * Constructs ajax loader
  3172. *
  3173. * @return string
  3174. */
  3175. function zb_AjaxLoader() {
  3176. $result = '
  3177. <script type="text/javascript">
  3178. function getXmlHttp()
  3179. {
  3180. var xmlhttp;
  3181. try
  3182. {
  3183. xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  3184. }
  3185. catch (e)
  3186. {
  3187. try
  3188. {
  3189. xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  3190. }
  3191. catch (E)
  3192. {
  3193. xmlhttp = false;
  3194. }
  3195. }
  3196. if(!xmlhttp && typeof XMLHttpRequest!=\'undefined\')
  3197. {
  3198. xmlhttp = new XMLHttpRequest();
  3199. }
  3200. return xmlhttp;
  3201. }
  3202. function goajax(link,container)
  3203. {
  3204. var myrequest = getXmlHttp()
  3205. var docum = link;
  3206. var contentElem = document.getElementById(container);
  3207. myrequest.open(\'POST\', docum, true);
  3208. myrequest.setRequestHeader(\'Content-Type\', \'application/x-www-form-urlencoded\');
  3209. myrequest.onreadystatechange = function()
  3210. {
  3211. if (myrequest.readyState == 4)
  3212. {
  3213. if(myrequest.status == 200)
  3214. {
  3215. var resText = myrequest.responseText;
  3216. var ua = navigator.userAgent.toLowerCase();
  3217. if (ua.indexOf(\'gecko\') != -1)
  3218. {
  3219. var range = contentElem.ownerDocument.createRange();
  3220. range.selectNodeContents(contentElem);
  3221. range.deleteContents();
  3222. var fragment = range.createContextualFragment(resText);
  3223. contentElem.appendChild(fragment);
  3224. }
  3225. else
  3226. {
  3227. contentElem.innerHTML = resText;
  3228. }
  3229. }
  3230. else
  3231. {
  3232. contentElem.innerHTML = \'' . __('Error') . '\';
  3233. }
  3234. }
  3235. }
  3236. myrequest.send();
  3237. }
  3238. </script>
  3239. ';
  3240. return ($result);
  3241. }
  3242. /**
  3243. * Construct JS hider
  3244. *
  3245. * @return string
  3246. */
  3247. function zb_JSHider() {
  3248. $result = '
  3249. <script language=javascript type=\'text/javascript\'>
  3250. function showhide(id){
  3251. if (document.getElementById){
  3252. obj = document.getElementById(id);
  3253. if (obj.style.display == "none"){
  3254. obj.style.display = "";
  3255. } else {
  3256. obj.style.display = "none";
  3257. }
  3258. }
  3259. }
  3260. </script>
  3261. ';
  3262. return ($result);
  3263. }
  3264. /**
  3265. * Gets list of ubilling database tables with some stats
  3266. *
  3267. * @return array
  3268. */
  3269. function zb_DBGetStats() {
  3270. $detail_query = "SHOW TABLE STATUS WHERE `Name` LIKE '%'";
  3271. $all = simple_queryall($detail_query);
  3272. $stats = array();
  3273. if (!empty($all)) {
  3274. foreach ($all as $io => $each) {
  3275. $filtered = array_values($each);
  3276. $stats[$filtered[0]]['name'] = $each['Name'];
  3277. $stats[$filtered[0]]['rows'] = $each['Rows'];
  3278. $stats[$filtered[0]]['size'] = $each['Data_length'];
  3279. $stats[$filtered[0]]['engine'] = $each['Engine'];
  3280. $stats[$filtered[0]]['collation'] = $each['Collation'];
  3281. $stats[$filtered[0]]['comment'] = $each['Comment'];
  3282. $stats[$filtered[0]]['raw'] = $each;
  3283. }
  3284. }
  3285. return ($stats);
  3286. }
  3287. /**
  3288. * Returns current database info in human readable view
  3289. *
  3290. * @return string
  3291. */
  3292. function zb_DBStatsRender() {
  3293. $all = zb_DBGetStats();
  3294. $result = '';
  3295. $totalRows = 0;
  3296. $totalSize = 0;
  3297. $totalCount = 0;
  3298. if (!empty($all)) {
  3299. $cells = wf_TableCell(__('Table name'));
  3300. $cells .= wf_TableCell(__('Engine'));
  3301. $cells .= wf_TableCell(__('Encoding'));
  3302. $cells .= wf_TableCell(__('Rows'));
  3303. $cells .= wf_TableCell(__('Size'));
  3304. $rows = wf_TableRow($cells, 'row1');
  3305. foreach ($all as $io => $each) {
  3306. $cells = wf_TableCell($each['name']);
  3307. if (!empty($each['rows'])) {
  3308. $dbrows = $each['rows'];
  3309. $totalRows = $totalRows + $each['rows'];;
  3310. } else {
  3311. $dbrows = 0;
  3312. }
  3313. if (!empty($each['engine'])) {
  3314. $tableEngine = $each['engine'];
  3315. } else {
  3316. $tableEngine = $each['comment'];
  3317. }
  3318. $cells .= wf_TableCell($tableEngine);
  3319. $cells .= wf_TableCell($each['collation']);
  3320. $cells .= wf_TableCell($dbrows);
  3321. if (!empty($each['size'])) {
  3322. @$size = stg_convert_size($each['size']);
  3323. $totalSize = $totalSize + $each['size'];
  3324. } else {
  3325. $size = '0 b';
  3326. }
  3327. $cells .= wf_TableCell($size, '', '', 'sorttable_customkey="' . $each['size'] . '"');
  3328. $rows .= wf_TableRow($cells, 'row3');
  3329. $totalCount++;
  3330. }
  3331. $result .= $rows;
  3332. $result .= wf_tag('b') . __('Total') . ': ' . wf_tag('b', true) . ' ' . __('Tables') . ' ' . $totalCount . ' ' . __('Rows') . ' ' . $totalRows . ' / ' . __('Size') . ' ' . stg_convert_size($totalSize);
  3333. }
  3334. return ($result);
  3335. }
  3336. /**
  3337. * Returns current database info in human readable view with ajax controls
  3338. *
  3339. * @return string
  3340. */
  3341. function zb_DBStatsRenderContainer() {
  3342. global $ubillingDatabaseDriver;
  3343. $messages = new UbillingMessageHelper();
  3344. $result = '';
  3345. $result .= wf_AjaxLoader();
  3346. $result .= wf_AjaxLink('?module=report_sysload&ajaxdbstats=true', wf_img_sized('skins/icon_stats.gif', '', 16, 16) . ' ' . __('Database stats'), 'dbscontainer', false, 'ubButton');
  3347. $result .= wf_AjaxLink('?module=report_sysload&ajaxdbcheck=true', wf_img_sized('skins/icon_repair.gif', '', 16, 16) . ' ' . __('Check database'), 'dbscontainer', false, 'ubButton');
  3348. if (cfr('ROOT')) {
  3349. $result .= wf_Link(DBmon::URL_ME, wf_img('skins/icon_time_small.png') . ' ' . __('Database monitor'), false, 'ubButton') . ' ';
  3350. if (SQL_DEBUG) {
  3351. $backUrl = '';
  3352. if (!empty($_SERVER['REQUEST_URI'])) {
  3353. $backUrl = '&back=' . base64_encode($_SERVER['REQUEST_URI']);
  3354. }
  3355. $result .= wf_Link('?module=sqldebug' . $backUrl, wf_img('skins/log_icon_small.png') . ' ' . __('All SQL queries log'), true, 'ubButton');
  3356. }
  3357. }
  3358. $result .= $messages->getStyledMessage(__('Using MySQL PHP extension') . ': ' . $ubillingDatabaseDriver, 'info');
  3359. $result .= wf_tag('br');
  3360. $result .= wf_AjaxContainer('dbrepaircontainer');
  3361. $result .= wf_tag('table', false, 'sortable', 'width="100%" border="0" id="dbscontainer"') . zb_DBStatsRender() . wf_tag('table', true);
  3362. return ($result);
  3363. }
  3364. /**
  3365. * checks database table state
  3366. *
  3367. * @return string
  3368. */
  3369. function zb_DBCheckTable($tablename) {
  3370. $result = '';
  3371. if (!empty($tablename)) {
  3372. $query = "CHECK TABLE `" . $tablename . "`";
  3373. $data = simple_query($query);
  3374. if (!empty($data)) {
  3375. $result = $data['Msg_text'];
  3376. }
  3377. }
  3378. return ($result);
  3379. }
  3380. /**
  3381. * Trys to repair corrupted database table
  3382. *
  3383. * @param string $tableName
  3384. *
  3385. * @return string
  3386. */
  3387. function zb_DBRepairTable($tableName) {
  3388. $tableNameF = mysql_real_escape_string($tableName);
  3389. $query = "REPAIR TABLE `" . $tableNameF . "`;";
  3390. nr_query($query);
  3391. log_register('DATABASE TABLE `' . $tableName . '` REPAIRED');
  3392. $messages = new UbillingMessageHelper();
  3393. $repairResult_q = "CHECK TABLE `" . $tableNameF . "`";
  3394. $repairResult = simple_query($repairResult_q);
  3395. $result = $messages->getStyledMessage(__('Database table') . ' `' . $tableName . '` ' . __('was repaired') . '. ' . __('Now table status is') . ' "' . $repairResult['Msg_text'] . '"', 'success');
  3396. return ($result);
  3397. }
  3398. /**
  3399. * Returns current database info in human readable view and table check
  3400. *
  3401. * @return string
  3402. */
  3403. function zb_DBCheckRender() {
  3404. $all = zb_DBGetStats();
  3405. if (!empty($all)) {
  3406. $cells = wf_TableCell(__('Table name'));
  3407. $cells .= wf_TableCell(__('Status'));
  3408. $rows = wf_TableRow($cells, 'row1');
  3409. foreach ($all as $io => $each) {
  3410. $cells = wf_TableCell($each['name']);
  3411. $tableStatus = zb_DBCheckTable($each['name']);
  3412. $fixControl = '';
  3413. if ($tableStatus != 'OK') {
  3414. $fixControl = ' ' . wf_AjaxLink('?module=report_sysload&dbrepairtable=' . $each['name'], wf_img('skins/icon_repair.gif', __('Fix')), 'dbrepaircontainer');
  3415. }
  3416. $cells .= wf_TableCell($tableStatus . $fixControl);
  3417. $rows .= wf_TableRow($cells, 'row3');
  3418. }
  3419. }
  3420. return ($rows);
  3421. }
  3422. /**
  3423. * UTF8-safe translit function
  3424. *
  3425. * @param $string string to be transliterated
  3426. * @param $bool Save case state
  3427. *
  3428. * @return string
  3429. */
  3430. function zb_TranslitString($string, $caseSensetive = false) {
  3431. if ($caseSensetive) {
  3432. $replace = array(
  3433. "'" => "",
  3434. "`" => "",
  3435. "а" => "a",
  3436. "А" => "A",
  3437. "б" => "b",
  3438. "Б" => "B",
  3439. "в" => "v",
  3440. "В" => "V",
  3441. "г" => "g",
  3442. "Г" => "G",
  3443. "д" => "d",
  3444. "Д" => "D",
  3445. "е" => "e",
  3446. "Е" => "E",
  3447. "ё" => "e",
  3448. "Ё" => "E",
  3449. "ж" => "zh",
  3450. "Ж" => "Zh",
  3451. "з" => "z",
  3452. "З" => "Z",
  3453. "и" => "y",
  3454. "И" => "Y",
  3455. "й" => "y",
  3456. "Й" => "Y",
  3457. "к" => "k",
  3458. "К" => "K",
  3459. "л" => "l",
  3460. "Л" => "L",
  3461. "м" => "m",
  3462. "М" => "M",
  3463. "н" => "n",
  3464. "Н" => "N",
  3465. "о" => "o",
  3466. "О" => "O",
  3467. "п" => "p",
  3468. "П" => "P",
  3469. "р" => "r",
  3470. "Р" => "R",
  3471. "с" => "s",
  3472. "С" => "S",
  3473. "т" => "t",
  3474. "Т" => "T",
  3475. "у" => "u",
  3476. "У" => "U",
  3477. "ф" => "f",
  3478. "Ф" => "F",
  3479. "х" => "h",
  3480. "Х" => "H",
  3481. "ц" => "c",
  3482. "Ц" => "C",
  3483. "ч" => "ch",
  3484. "Ч" => "Ch",
  3485. "ш" => "sh",
  3486. "Ш" => "Sh",
  3487. "щ" => "sch",
  3488. "Щ" => "Sch",
  3489. "ъ" => "",
  3490. "Ъ" => "",
  3491. "ы" => "y",
  3492. "Ы" => "Y",
  3493. "ь" => "",
  3494. "Ь" => "",
  3495. "э" => "e",
  3496. "Э" => "E",
  3497. "ю" => "yu",
  3498. "Ю" => "Yu",
  3499. "я" => "ya",
  3500. "Я" => "Ya",
  3501. "і" => "i",
  3502. "І" => "I",
  3503. "ї" => "yi",
  3504. "Ї" => "Yi",
  3505. "є" => "e",
  3506. "Є" => "E",
  3507. "ґ" => "g",
  3508. "Ґ" => "G"
  3509. );
  3510. if (curlang() == 'ru') {
  3511. $replace['и'] = 'i';
  3512. $replace['И'] = 'I';
  3513. }
  3514. } else {
  3515. $replace = array(
  3516. "'" => "",
  3517. "`" => "",
  3518. "а" => "a",
  3519. "А" => "a",
  3520. "б" => "b",
  3521. "Б" => "b",
  3522. "в" => "v",
  3523. "В" => "v",
  3524. "г" => "g",
  3525. "Г" => "g",
  3526. "д" => "d",
  3527. "Д" => "d",
  3528. "е" => "e",
  3529. "Е" => "e",
  3530. "ё" => "e",
  3531. "Ё" => "e",
  3532. "ж" => "zh",
  3533. "Ж" => "zh",
  3534. "з" => "z",
  3535. "З" => "z",
  3536. "и" => "y",
  3537. "И" => "y",
  3538. "й" => "y",
  3539. "Й" => "y",
  3540. "к" => "k",
  3541. "К" => "k",
  3542. "л" => "l",
  3543. "Л" => "l",
  3544. "м" => "m",
  3545. "М" => "m",
  3546. "н" => "n",
  3547. "Н" => "n",
  3548. "о" => "o",
  3549. "О" => "o",
  3550. "п" => "p",
  3551. "П" => "p",
  3552. "р" => "r",
  3553. "Р" => "r",
  3554. "с" => "s",
  3555. "С" => "s",
  3556. "т" => "t",
  3557. "Т" => "t",
  3558. "у" => "u",
  3559. "У" => "u",
  3560. "ф" => "f",
  3561. "Ф" => "f",
  3562. "х" => "h",
  3563. "Х" => "h",
  3564. "ц" => "c",
  3565. "Ц" => "c",
  3566. "ч" => "ch",
  3567. "Ч" => "ch",
  3568. "ш" => "sh",
  3569. "Ш" => "sh",
  3570. "щ" => "sch",
  3571. "Щ" => "sch",
  3572. "ъ" => "",
  3573. "Ъ" => "",
  3574. "ы" => "y",
  3575. "Ы" => "y",
  3576. "ь" => "",
  3577. "Ь" => "",
  3578. "э" => "e",
  3579. "Э" => "e",
  3580. "ю" => "yu",
  3581. "Ю" => "yu",
  3582. "я" => "ya",
  3583. "Я" => "ya",
  3584. "і" => "i",
  3585. "І" => "i",
  3586. "ї" => "yi",
  3587. "Ї" => "yi",
  3588. "є" => "e",
  3589. "Є" => "e",
  3590. "ґ" => "g",
  3591. "Ґ" => "g"
  3592. );
  3593. if (curlang() == 'ru') {
  3594. $replace['и'] = 'i';
  3595. $replace['И'] = 'i';
  3596. }
  3597. }
  3598. return $str = iconv("UTF-8", "UTF-8//IGNORE", strtr($string, $replace));
  3599. }
  3600. /**
  3601. * Rounds $value to $precision digits
  3602. *
  3603. * @param $value Integer which to round
  3604. * @param $precision Amount of digits after point
  3605. * @return float
  3606. *
  3607. */
  3608. function web_roundValue($value, $precision = 2) {
  3609. $precision = ($precision < 0) ? 0 : $precision;
  3610. $multiplier = pow(10, $precision);
  3611. $rounded = (($value >= 0) ? ceil($value * $multiplier) : floor($value * $multiplier)) / $multiplier;
  3612. return $rounded;
  3613. }
  3614. /**
  3615. * Big values cash display formatting for better readability
  3616. *
  3617. * @param float $cashValue
  3618. *
  3619. * @return string
  3620. */
  3621. function zb_CashBigValueFormat($cashValue) {
  3622. return (number_format($cashValue, 0, '.', ' '));
  3623. }
  3624. /**
  3625. * Returns array of year signups per month
  3626. *
  3627. * @param int $year
  3628. * @return array
  3629. */
  3630. function zb_AnalyticsSignupsGetCountYear($year) {
  3631. $year = vf($year, 3);
  3632. $months = months_array();
  3633. $result = array();
  3634. $tmpArr = array();
  3635. $query = "SELECT * from `userreg` WHERE `date` LIKE '" . $year . "-%'";
  3636. $all = simple_queryall($query);
  3637. if (!empty($all)) {
  3638. foreach ($all as $io => $each) {
  3639. $time = strtotime($each['date']);
  3640. $month = date("m", $time);
  3641. if (isset($tmpArr[$month])) {
  3642. $tmpArr[$month]['count']++;
  3643. } else {
  3644. $tmpArr[$month]['count'] = 1;
  3645. }
  3646. }
  3647. }
  3648. foreach ($months as $eachmonth => $monthname) {
  3649. $result[$eachmonth] = (isset($tmpArr[$eachmonth])) ? $tmpArr[$eachmonth]['count'] : 0;
  3650. }
  3651. return ($result);
  3652. }
  3653. /**
  3654. * Returns singup requests for some year per month
  3655. *
  3656. * @param int $year
  3657. * @return array
  3658. */
  3659. function zb_AnalyticsSigReqGetCountYear($year) {
  3660. $year = vf($year, 3);
  3661. $months = months_array();
  3662. $result = array();
  3663. $tmpArr = array();
  3664. $query = "SELECT * from `sigreq` WHERE `date` LIKE '" . $year . "-%'";
  3665. $all = simple_queryall($query);
  3666. if (!empty($all)) {
  3667. foreach ($all as $io => $each) {
  3668. $time = strtotime($each['date']);
  3669. $month = date("m", $time);
  3670. if (isset($tmpArr[$month])) {
  3671. $tmpArr[$month]['count']++;
  3672. } else {
  3673. $tmpArr[$month]['count'] = 1;
  3674. }
  3675. }
  3676. }
  3677. foreach ($months as $eachmonth => $monthname) {
  3678. $monthcount = (isset($tmpArr[$eachmonth])) ? $tmpArr[$eachmonth]['count'] : 0;
  3679. $result[$eachmonth] = $monthcount;
  3680. }
  3681. return ($result);
  3682. }
  3683. /**
  3684. * Returns array of tickets recieved during the year or month, or something else
  3685. *
  3686. * @param int $datefilter - format like "year" or "year-month" or "year-month-day"
  3687. *
  3688. * @return array as month=>count
  3689. */
  3690. function zb_AnalyticsTicketingGetCountYear($datefilter) {
  3691. $datefilter = mysql_real_escape_string($datefilter);
  3692. $months = months_array();
  3693. $result = array();
  3694. $tmpArr = array();
  3695. $query = "SELECT * from `ticketing` WHERE `date` LIKE '" . $datefilter . "-%' AND `from` != 'NULL';";
  3696. $all = simple_queryall($query);
  3697. if (!empty($all)) {
  3698. foreach ($all as $io => $each) {
  3699. $time = strtotime($each['date']);
  3700. $month = date("m", $time);
  3701. if (isset($tmpArr[$month])) {
  3702. $tmpArr[$month]['count']++;
  3703. } else {
  3704. $tmpArr[$month]['count'] = 1;
  3705. }
  3706. }
  3707. }
  3708. foreach ($months as $eachmonth => $monthname) {
  3709. $monthcount = (isset($tmpArr[$eachmonth])) ? $tmpArr[$eachmonth]['count'] : 0;
  3710. $result[$eachmonth] = $monthcount;
  3711. }
  3712. return ($result);
  3713. }
  3714. /**
  3715. * Returns array of planned tasks per year
  3716. *
  3717. * @param int $year
  3718. * @return array
  3719. */
  3720. function zb_AnalyticsTaskmanGetCountYear($year) {
  3721. $year = vf($year, 3);
  3722. $months = months_array();
  3723. $result = array();
  3724. $tmpArr = array();
  3725. $query = "SELECT * from `taskman` WHERE `date` LIKE '" . $year . "-%'";
  3726. $all = simple_queryall($query);
  3727. if (!empty($all)) {
  3728. foreach ($all as $io => $each) {
  3729. $time = strtotime($each['date']);
  3730. $month = date("m", $time);
  3731. if (isset($tmpArr[$month])) {
  3732. $tmpArr[$month]['count']++;
  3733. } else {
  3734. $tmpArr[$month]['count'] = 1;
  3735. }
  3736. }
  3737. }
  3738. foreach ($months as $eachmonth => $monthname) {
  3739. $monthcount = (isset($tmpArr[$eachmonth])) ? $tmpArr[$eachmonth]['count'] : 0;
  3740. $result[$eachmonth] = $monthcount;
  3741. }
  3742. return ($result);
  3743. }
  3744. /**
  3745. * Initializes file download procedure
  3746. *
  3747. * @param string $filePath
  3748. * @param string $contentType
  3749. * @throws Exception
  3750. */
  3751. function zb_DownloadFile($filePath, $contentType = '') {
  3752. if (!empty($filePath)) {
  3753. if (file_exists($filePath)) {
  3754. log_register("DOWNLOAD FILE `" . $filePath . "`");
  3755. if (($contentType == '') or ($contentType == 'default')) {
  3756. $contentType = 'application/octet-stream';
  3757. } else {
  3758. //additional content types
  3759. if ($contentType == 'docx') {
  3760. $contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
  3761. }
  3762. if ($contentType == 'csv') {
  3763. $contentType = 'text/csv; charset=Windows-1251';
  3764. }
  3765. if ($contentType == 'excel') {
  3766. $contentType = 'application/vnd.ms-excel';
  3767. }
  3768. if ($contentType == 'text') {
  3769. $contentType = 'text/plain;';
  3770. }
  3771. if ($contentType == 'jpg') {
  3772. $contentType = 'Content-Type: image/jpeg';
  3773. }
  3774. if ($contentType == 'png') {
  3775. $contentType = 'Content-Type: image/png';
  3776. }
  3777. }
  3778. header('Content-Type: ' . $contentType);
  3779. header("Content-Transfer-Encoding: Binary");
  3780. header("Content-disposition: attachment; filename=\"" . basename($filePath) . "\"");
  3781. header("Content-Description: File Transfer");
  3782. header("Accept-Ranges: 'bytes'");
  3783. header("Content-Length: " . filesize($filePath));
  3784. flush(); // this doesn't really matter.
  3785. $fp = fopen($filePath, "r");
  3786. while (!feof($fp)) {
  3787. echo fread($fp, 65536);
  3788. flush(); // this is essential for large downloads
  3789. }
  3790. fclose($fp);
  3791. die();
  3792. } else {
  3793. throw new Exception('DOWNLOAD_FILEPATH_NOT_EXISTS');
  3794. }
  3795. } else {
  3796. throw new Exception('DOWNLOAD_FILEPATH_EMPTY');
  3797. }
  3798. }
  3799. /**
  3800. * Returns current stargazer DB version
  3801. * =<2.408 - 0
  3802. * >=2.409 - 1+
  3803. *
  3804. * @return int
  3805. */
  3806. function zb_CheckDbSchema() {
  3807. if (zb_CheckTableExists('info')) {
  3808. $query = "SELECT `version` from `info`";
  3809. $result = simple_query($query);
  3810. $result = $result['version'];
  3811. } else {
  3812. $result = 0;
  3813. }
  3814. return ($result);
  3815. }
  3816. /**
  3817. * Returns swtitch and port assign form. Includes internal controller.
  3818. *
  3819. * @param string $login
  3820. * @param array $allswitches
  3821. * @param array $allportassigndata
  3822. * @param int $suggestswitchid
  3823. * @param int $suggestswitchport
  3824. * @return string
  3825. */
  3826. function web_SnmpSwitchControlForm($login, $allswitches, $allportassigndata, $suggestswitchid = '', $suggestswitchport = '') {
  3827. $login = mysql_real_escape_string($login);
  3828. $switcharr = array();
  3829. if (!empty($allswitches)) {
  3830. foreach ($allswitches as $io => $eachswitch) {
  3831. $switcharr[$eachswitch['id']] = $eachswitch['ip'] . ' - ' . $eachswitch['location'];
  3832. }
  3833. }
  3834. //getting current data
  3835. $assignData = array();
  3836. if (isset($allportassigndata[$login])) {
  3837. $assignData = $allportassigndata[$login];
  3838. }
  3839. $sameUsers = '';
  3840. if (!empty($assignData)) {
  3841. $currentSwitchPort = $assignData['port'];
  3842. $currentSwitchId = $assignData['switchid'];
  3843. } else {
  3844. $currentSwitchPort = '';
  3845. $currentSwitchId = '';
  3846. }
  3847. //control form construct
  3848. $inputs = wf_HiddenInput('swassignlogin', $login);
  3849. $inputs .= wf_Selector('swassignswid', $switcharr, __('Switch'), $suggestswitchid, true);
  3850. $inputs .= wf_TextInput('swassignswport', __('Port'), $suggestswitchport, false, '2');
  3851. $inputs .= wf_CheckInput('swassigndelete', __('Delete'), true, false);
  3852. $inputs .= wf_Submit('Save');
  3853. $controlForm = wf_Form('', "POST", $inputs, 'glamour');
  3854. //form end
  3855. $switchAssignController = wf_modal(web_edit_icon(), __('Switch port assign'), $controlForm, '', '450', '200');
  3856. $cells = wf_TableCell(__('Switch'), '30%', 'row2');
  3857. $cells .= wf_TableCell(@$switcharr[$currentSwitchId]);
  3858. $rows = wf_TableRow($cells, 'row3');
  3859. $cells = wf_TableCell(__('Port'), '30%', 'row2');
  3860. $cells .= wf_TableCell($currentSwitchPort);
  3861. $rows .= wf_TableRow($cells, 'row3');
  3862. $cells = wf_TableCell(__('Change'), '30%', 'row2');
  3863. $cells .= wf_TableCell($switchAssignController);
  3864. $rows .= wf_TableRow($cells, 'row3');
  3865. $result = wf_TableBody($rows, '100%', '0');
  3866. //update subroutine
  3867. if (wf_CheckPost(array('swassignlogin', 'swassignswid', 'swassignswport'))) {
  3868. $newswid = vf($_POST['swassignswid'], 3);
  3869. $newport = vf($_POST['swassignswport'], 3);
  3870. nr_query("DELETE from `switchportassign` WHERE `login`='" . $_POST['swassignlogin'] . "'");
  3871. nr_query("INSERT INTO `switchportassign` (`id` ,`login` ,`switchid` ,`port`) VALUES (NULL , '" . $_POST['swassignlogin'] . "', '" . $newswid . "', '" . $newport . "');");
  3872. log_register("CHANGE SWITCHPORT (" . $login . ") ON SWITCHID [" . $newswid . "] PORT [" . $newport . "]");
  3873. rcms_redirect('?module=switchpoller&switchid=' . $suggestswitchid);
  3874. }
  3875. //delete subroutine
  3876. if (isset($_POST['swassigndelete'])) {
  3877. nr_query("DELETE from `switchportassign` WHERE `login`='" . $_POST['swassignlogin'] . "'");
  3878. log_register("DELETE SWITCHPORT (" . $login . ")");
  3879. rcms_redirect('?module=switchpoller&switchid=' . $suggestswitchid);
  3880. }
  3881. return ($result);
  3882. }
  3883. /**
  3884. * Returns array of Stargazer tariffs payment periods as tariffname=>period
  3885. *
  3886. * @return array
  3887. */
  3888. function zb_TariffGetPeriodsAll() {
  3889. $result = array();
  3890. $dbSchema = zb_CheckDbSchema();
  3891. if ($dbSchema > 0) {
  3892. //stargazer >= 2.409
  3893. $query = "SELECT `name`,`period` from `tariffs`";
  3894. $all = simple_queryall($query);
  3895. if (!empty($all)) {
  3896. foreach ($all as $io => $eachtariff) {
  3897. $result[$eachtariff['name']] = $eachtariff['period'];
  3898. }
  3899. }
  3900. } else {
  3901. //stargazer 2.408
  3902. $query = "SELECT `name` from `tariffs`";
  3903. $all = simple_queryall($query);
  3904. if (!empty($all)) {
  3905. foreach ($all as $io => $eachtariff) {
  3906. $result[$eachtariff['name']] = 'month';
  3907. }
  3908. }
  3909. }
  3910. return ($result);
  3911. }
  3912. /**
  3913. * logs succeful self credit fact into database
  3914. *
  3915. * @param string $login existing users login
  3916. *
  3917. * @return void
  3918. */
  3919. function zb_CreditLogPush($login) {
  3920. $login = mysql_real_escape_string($login);
  3921. $date = curdatetime();
  3922. $query = "INSERT INTO `zbssclog` (`id` , `date` , `login` ) VALUES ( NULL , '" . $date . "', '" . $login . "');";
  3923. nr_query($query);
  3924. }
  3925. /**
  3926. * Checks if user use SC module without previous payment and returns false if used or true if feature available
  3927. *
  3928. * @param string $login existing users login
  3929. *
  3930. * @return bool
  3931. */
  3932. function zb_CreditLogCheckHack($login) {
  3933. $login = mysql_real_escape_string($login);
  3934. $query = "SELECT `note` FROM `payments` WHERE `login` = '" . $login . "' AND (`summ` > 0 OR `note` = 'SCFEE') ORDER BY `payments`.`date` DESC LIMIT 1";
  3935. $data = simple_query($query);
  3936. if (empty($data)) {
  3937. return (true);
  3938. } elseif (!empty($data) and $data['note'] != 'SCFEE') {
  3939. return (true);
  3940. } else {
  3941. return (false);
  3942. }
  3943. }
  3944. /**
  3945. * Checks is user tariff allowed for use of credit feature
  3946. *
  3947. * @param array $sc_allowed
  3948. * @param string $usertariff
  3949. * @return bool
  3950. */
  3951. function zb_CreditCheckAllowed($sc_allowed, $usertariff) {
  3952. $result = true;
  3953. if (!empty($sc_allowed)) {
  3954. if (isset($sc_allowed[$usertariff])) {
  3955. $result = true;
  3956. } else {
  3957. $result = false;
  3958. }
  3959. }
  3960. return ($result);
  3961. }
  3962. /**
  3963. * checks is user current month use SC module and returns false if used or true if feature available
  3964. *
  3965. * @param string $login existing users login
  3966. *
  3967. * @return bool
  3968. */
  3969. function zb_CreditLogCheckMonth($login) {
  3970. $login = mysql_real_escape_string($login);
  3971. $pattern = date("Y-m");
  3972. $query = "SELECT `id` from `zbssclog` WHERE `login` LIKE '" . $login . "' AND `date` LIKE '" . $pattern . "%';";
  3973. $data = simple_query($query);
  3974. if (empty($data)) {
  3975. return (true);
  3976. } else {
  3977. return (false);
  3978. }
  3979. }
  3980. /**
  3981. * Returns all users used SC module this month
  3982. *
  3983. * @return array
  3984. */
  3985. function zb_CreditLogGetAll() {
  3986. $result = array();
  3987. $pattern = date("Y-m");
  3988. $query = "SELECT `login`,`id`,`date` from `zbssclog` WHERE `date` LIKE '" . $pattern . "%';";
  3989. $all = simple_queryall($query);
  3990. if (!empty($all)) {
  3991. foreach ($all as $io => $each) {
  3992. $result[$each['login']] = $each['date'];
  3993. }
  3994. }
  3995. return ($result);
  3996. }
  3997. /**
  3998. * Returns one-click credit set form for profile
  3999. *
  4000. *
  4001. * @param string $login existing callback user login
  4002. * @param float $cash current user balance
  4003. * @param int $credit current user credit
  4004. * @param string $userTariff current user tariff
  4005. * @param int $easycreditoption current state of EASY_CREDIT option
  4006. *
  4007. * @return string
  4008. */
  4009. function web_EasyCreditForm($login, $cash, $credit, $userTariff, $easycreditoption) {
  4010. if (ubRouting::checkPost(array('easycreditlogin', 'easycreditlimit', 'easycreditexpire'))) {
  4011. global $billing;
  4012. global $ubillingConfig;
  4013. $altCfg = $ubillingConfig->getAlter();
  4014. $setCredit = ubRouting::post('easycreditlimit', 'vf');
  4015. $setLogin = ubRouting::post('easycreditlogin', 'mres');
  4016. $setExpire = ubRouting::post('easycreditexpire', 'mres');
  4017. $creditLimitOpt = $altCfg['STRICT_CREDIT_LIMIT'];
  4018. $creditAllowedFlag = false;
  4019. if (zb_checkDate($setExpire)) {
  4020. if (zb_checkMoney($setCredit)) {
  4021. if ($creditLimitOpt != 'DISABLED') {
  4022. if ($setCredit <= $creditLimitOpt) {
  4023. $creditAllowedFlag = true;
  4024. } else {
  4025. log_register('FAIL Credit (' . $login . ') LIMIT `' . $setCredit . '` HAWK TUAH `' . $creditLimitOpt . '`');
  4026. show_error(__('The amount of allowed credit limit has been exceeded'));
  4027. // Ooh, baby, do you know what that's worth?
  4028. // Ooh, heaven is a place on earth
  4029. }
  4030. } else {
  4031. //strict credit disabled
  4032. $creditAllowedFlag = true;
  4033. }
  4034. } else {
  4035. show_error(__('Wrong format of money sum'));
  4036. log_register('EASYCREDIT FAIL WRONG SUMM `' . $setCredit . '`');
  4037. }
  4038. } else {
  4039. show_error(__('Wrong date format'));
  4040. log_register('EASYCREDIT FAIL DATEFORMAT `' . $setExpire . '`');
  4041. }
  4042. if ($creditAllowedFlag) {
  4043. //set credit
  4044. $billing->setcredit($setLogin, $setCredit);
  4045. log_register('CHANGE Credit (' . $setLogin . ') ON ' . $setCredit);
  4046. //set credit expire date
  4047. $billing->setcreditexpire($setLogin, $setExpire);
  4048. log_register('CHANGE CreditExpire (' . $setLogin . ') ON ' . $setExpire);
  4049. ubRouting::nav('?module=userprofile&username=' . $setLogin);
  4050. }
  4051. }
  4052. $allTariffsData = zb_TariffGetAllData();
  4053. @$tariffPrice = (isset($allTariffsData[$userTariff])) ? $allTariffsData[$userTariff]['Fee'] : 0;
  4054. $tariffPeriod = 'month';
  4055. if ($tariffPrice) {
  4056. //some valid tariff
  4057. if (isset($allTariffsData[$userTariff]['period'])) {
  4058. $tariffPeriod = $allTariffsData[$userTariff]['period'];
  4059. }
  4060. }
  4061. if ($cash >= '-' . $credit) {
  4062. $creditProposal = $tariffPrice;
  4063. $creditNote = __('The amount of money in the account at the moment is sufficient to provide the service. It is therefore proposed to set a credit limit on the fee of the tariff.');
  4064. //daily tariffs fix for active users
  4065. if ($tariffPeriod == 'day') {
  4066. $creditProposal = $tariffPrice * $easycreditoption;
  4067. $creditNote = __('The amount of money in the account at the moment is sufficient to provide the service. It is therefore proposed to set a credit limit on the fee of the tariff.');
  4068. $creditNote .= ' + ' . $easycreditoption . ' ' . __('days') . '.';
  4069. }
  4070. } else {
  4071. $creditProposal = abs($cash);
  4072. $creditNote = __('At the moment the account have debt. It is proposed to establish credit in its size.');
  4073. //daily tariffs fix for debtors
  4074. if ($tariffPeriod == 'day') {
  4075. $creditProposal = abs($cash) + ($tariffPrice * $easycreditoption);
  4076. $creditNote = __('At the moment the account have debt. It is proposed to establish credit in its size.');
  4077. $creditNote .= ' + ' . $easycreditoption . ' ' . __('days') . '.';
  4078. }
  4079. //small and ugly hack to avoid precision issues with floating point values
  4080. if (ispos($creditProposal, '.')) {
  4081. $creditProposal = $creditProposal + 1;
  4082. $creditProposal = round($creditProposal);
  4083. }
  4084. }
  4085. //calculate credit expire date
  4086. $nowTimestamp = time();
  4087. $creditSeconds = ($easycreditoption * 86400); //days*secs
  4088. $creditOffset = $nowTimestamp + $creditSeconds;
  4089. $creditExpireDate = date("Y-m-d", $creditOffset);
  4090. //construct form
  4091. $controlIcon = wf_tag('img', false, '', 'src="skins/icon_calendar.gif" height="10"');
  4092. $inputs = '';
  4093. $inputs .= wf_HiddenInput('easycreditlogin', $login);
  4094. $inputs .= wf_TextInput('easycreditlimit', '', $creditProposal, false, 5, 'finance') . __('credit limit') . ' ';
  4095. $inputs .= __('until');
  4096. $inputs .= wf_DatePickerPreset('easycreditexpire', $creditExpireDate);
  4097. $inputs .= wf_Submit(__('Save'));
  4098. $form = wf_Form('?module=userprofile&username=' . $login, 'POST', $inputs, 'glamour');
  4099. $form .= $creditNote;
  4100. $result = wf_modal($controlIcon, __('Change') . ' ' . __('credit limit'), $form, '', '500', '180');
  4101. return ($result);
  4102. }
  4103. /**
  4104. * Returns custom report sysload scripts output
  4105. *
  4106. * @param string $scriptoption option from alter.ini -> SYSLOAD_CUSTOM_SCRIPTS
  4107. *
  4108. * @return string
  4109. */
  4110. function web_ReportSysloadCustomScripts($scriptoption) {
  4111. $result = '';
  4112. //internal script ajax handling
  4113. if (wf_CheckGet(array('ajxcscrun'))) {
  4114. $runpath = base64_decode($_GET['ajxcscrun']);
  4115. if (!empty($runpath)) {
  4116. $script_result = wf_tag('pre') . shell_exec($runpath) . wf_tag('pre', true);
  4117. die($script_result);
  4118. }
  4119. }
  4120. $scriptdata = explode(',', $scriptoption);
  4121. if (!empty($scriptdata)) {
  4122. $result .= wf_AjaxLoader();
  4123. foreach ($scriptdata as $io => $eachscript) {
  4124. $curScript = explode(':', $eachscript);
  4125. if (!empty($curScript)) {
  4126. $name = $curScript[0];
  4127. $path = $curScript[1];
  4128. $result .= wf_AjaxLink('?module=report_sysload&ajxcscrun=' . base64_encode($path), wf_img('skins/script16.png') . ' ' . $name, 'custommoncontainder', false, 'ubButton');
  4129. }
  4130. }
  4131. $result .= wf_delimiter();
  4132. $result .= wf_tag('span', false, '', 'id="custommoncontainder"') . wf_tag('span', true);
  4133. }
  4134. return ($result);
  4135. }
  4136. /**
  4137. * Native XML parser function
  4138. *
  4139. * @param string $contents
  4140. * @param int $get_attributes
  4141. * @param string $priority
  4142. * @return array
  4143. */
  4144. function zb_xml2array($contents, $get_attributes = 1, $priority = 'tag') {
  4145. if (!$contents)
  4146. return array();
  4147. if (!function_exists('xml_parser_create')) {
  4148. print "'xml_parser_create()' function not found!";
  4149. return array();
  4150. }
  4151. //Get the XML parser of PHP - PHP must have this module for the parser to work
  4152. $parser = xml_parser_create('');
  4153. xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
  4154. xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
  4155. xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
  4156. xml_parse_into_struct($parser, trim($contents), $xml_values);
  4157. xml_parser_free($parser);
  4158. if (!$xml_values)
  4159. return; //Hmm...
  4160. //Initializations
  4161. $xml_array = array();
  4162. $parents = array();
  4163. $opened_tags = array();
  4164. $arr = array();
  4165. $current = &$xml_array; //Refference
  4166. //Go through the tags.
  4167. $repeated_tag_index = array(); //Multiple tags with same name will be turned into an array
  4168. foreach ($xml_values as $data) {
  4169. unset($attributes, $value); //Remove existing values, or there will be trouble
  4170. //This command will extract these variables into the foreach scope
  4171. // tag(string), type(string), level(int), attributes(array).
  4172. extract($data); //We could use the array by itself, but this cooler.
  4173. $result = array();
  4174. $attributes_data = array();
  4175. if (isset($value)) {
  4176. if ($priority == 'tag')
  4177. $result = $value;
  4178. else
  4179. $result['value'] = $value; //Put the value in a assoc array if we are in the 'Attribute' mode
  4180. }
  4181. //Set the attributes too.
  4182. if (isset($attributes) and $get_attributes) {
  4183. foreach ($attributes as $attr => $val) {
  4184. if ($priority == 'tag')
  4185. $attributes_data[$attr] = $val;
  4186. else
  4187. $result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
  4188. }
  4189. }
  4190. //See tag status and do the needed.
  4191. if ($type == "open") { //The starting of the tag '<tag>'
  4192. $parent[$level - 1] = &$current;
  4193. if (!is_array($current) or (!in_array($tag, array_keys($current)))) { //Insert New tag
  4194. $current[$tag] = $result;
  4195. if ($attributes_data)
  4196. $current[$tag . '_attr'] = $attributes_data;
  4197. $repeated_tag_index[$tag . '_' . $level] = 1;
  4198. $current = &$current[$tag];
  4199. } else { //There was another element with the same tag name
  4200. if (isset($current[$tag][0])) { //If there is a 0th element it is already an array
  4201. $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
  4202. $repeated_tag_index[$tag . '_' . $level]++;
  4203. } else { //This section will make the value an array if multiple tags with the same name appear together
  4204. $current[$tag] = array($current[$tag], $result); //This will combine the existing item and the new item together to make an array
  4205. $repeated_tag_index[$tag . '_' . $level] = 2;
  4206. if (isset($current[$tag . '_attr'])) { //The attribute of the last(0th) tag must be moved as well
  4207. $current[$tag]['0_attr'] = $current[$tag . '_attr'];
  4208. unset($current[$tag . '_attr']);
  4209. }
  4210. }
  4211. $last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
  4212. $current = &$current[$tag][$last_item_index];
  4213. }
  4214. } elseif ($type == "complete") { //Tags that ends in 1 line '<tag />'
  4215. //See if the key is already taken.
  4216. if (!isset($current[$tag])) { //New Key
  4217. $current[$tag] = $result;
  4218. $repeated_tag_index[$tag . '_' . $level] = 1;
  4219. if ($priority == 'tag' and $attributes_data)
  4220. $current[$tag . '_attr'] = $attributes_data;
  4221. } else { //If taken, put all things inside a list(array)
  4222. if (isset($current[$tag][0]) and is_array($current[$tag])) { //If it is already an array...
  4223. // ...push the new element into that array.
  4224. $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
  4225. if ($priority == 'tag' and $get_attributes and $attributes_data) {
  4226. $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
  4227. }
  4228. $repeated_tag_index[$tag . '_' . $level]++;
  4229. } else { //If it is not an array...
  4230. $current[$tag] = array($current[$tag], $result); //...Make it an array using using the existing value and the new value
  4231. $repeated_tag_index[$tag . '_' . $level] = 1;
  4232. if ($priority == 'tag' and $get_attributes) {
  4233. if (isset($current[$tag . '_attr'])) { //The attribute of the last(0th) tag must be moved as well
  4234. $current[$tag]['0_attr'] = $current[$tag . '_attr'];
  4235. unset($current[$tag . '_attr']);
  4236. }
  4237. if ($attributes_data) {
  4238. $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
  4239. }
  4240. }
  4241. $repeated_tag_index[$tag . '_' . $level]++; //0 and 1 index is already taken
  4242. }
  4243. }
  4244. } elseif ($type == 'close') { //End of tag '</tag>'
  4245. $current = &$parent[$level - 1];
  4246. }
  4247. }
  4248. return ($xml_array);
  4249. }
  4250. /**
  4251. * Checks is tariff protected by some user usage?
  4252. *
  4253. * @param string $tariffname Existing stargazer tariff name
  4254. * @return bool
  4255. */
  4256. function zb_TariffProtected($tariffname) {
  4257. global $ubillingConfig;
  4258. $altCfg = $ubillingConfig->getAlter();
  4259. $tariffname = mysql_real_escape_string($tariffname);
  4260. $query = "SELECT `login` from `users` WHERE `Tariff`='" . $tariffname . "' OR `TariffChange`='" . $tariffname . "' LIMIT 1;";
  4261. $raw = simple_query($query);
  4262. $result = (empty($raw)) ? false : true;
  4263. if (!$result) {
  4264. if (@$altCfg['DEALWITHIT_ENABLED']) {
  4265. $dwi = new nya_dealwithit();
  4266. $dwi->where('action', '=', 'tariffchange');
  4267. $dwi->where('param', '=', ubRouting::filters($tariffname, 'mres'));
  4268. $moveCount = $dwi->getAll();
  4269. $result = (empty($moveCount)) ? false : true;
  4270. }
  4271. }
  4272. return ($result);
  4273. }
  4274. /**
  4275. * Checks PHP loaded modules
  4276. *
  4277. * @return string
  4278. */
  4279. function zb_CheckPHPExtensions() {
  4280. $result = '';
  4281. if (file_exists(CONFIG_PATH . 'optsextcfg')) {
  4282. $allRequired = file_get_contents(CONFIG_PATH . 'optsextcfg');
  4283. if (!empty($allRequired)) {
  4284. $allRequired = explodeRows($allRequired);
  4285. if (!empty($allRequired)) {
  4286. foreach ($allRequired as $io => $each) {
  4287. if (!empty($each)) {
  4288. $each = trim($each);
  4289. $notice = '';
  4290. if (!extension_loaded($each)) {
  4291. switch ($each) {
  4292. case 'mysql':
  4293. $notice = ' ' . __('Deprecated in') . ' PHP 7.0';
  4294. break;
  4295. case 'ereg':
  4296. $notice = ' ' . __('Deprecated in') . ' PHP 7.0';
  4297. break;
  4298. case 'memcache':
  4299. $notice = ' ' . __('Deprecated in') . ' PHP 7.0';
  4300. break;
  4301. case 'xhprof':
  4302. $notice = ' ' . __('May require manual installation');
  4303. break;
  4304. }
  4305. $result .= wf_tag('span', false, 'alert_error') . __('PHP extension not found') . ': ' . $each . $notice . wf_tag('span', true);
  4306. } else {
  4307. $result .= wf_tag('span', false, 'alert_success') . __('PHP extension loaded') . ': ' . $each . wf_tag('span', true);
  4308. }
  4309. }
  4310. }
  4311. }
  4312. }
  4313. } else {
  4314. $result .= wf_tag('span', false, 'alert_error') . __('Strange exeption') . ': OPTSEXTCFG_NOT_FOUND' . wf_tag('span', true);
  4315. }
  4316. return ($result);
  4317. }
  4318. /**
  4319. * Validate a Gregorian date
  4320. *
  4321. * @param string $date Date in MySQL format
  4322. * @return bool
  4323. */
  4324. function zb_checkDate($date) {
  4325. $explode = explode('-', $date);
  4326. @$year = $explode[0];
  4327. @$month = $explode[1];
  4328. @$day = $explode[2];
  4329. $result = @checkdate($month, $day, $year);
  4330. return ($result);
  4331. }
  4332. /**
  4333. * Cuts last char of string
  4334. *
  4335. * @param string $string
  4336. * @return string
  4337. */
  4338. function zb_CutEnd($string) {
  4339. $string = substr($string, 0, -1);
  4340. return ($string);
  4341. }
  4342. /**
  4343. * Returns memcached usage stats
  4344. *
  4345. * @global object $ubillingConfig
  4346. * @return string
  4347. */
  4348. function web_MemCachedRenderStats() {
  4349. global $ubillingConfig;
  4350. $altCfg = $ubillingConfig->getAlter();
  4351. $result = '';
  4352. $memcachedHost = 'localhost';
  4353. $memcachedPort = 11211;
  4354. $cacheEfficiency = '';
  4355. if (isset($altCfg['MEMCACHED_SERVER'])) {
  4356. $memcachedHost = $altCfg['MEMCACHED_SERVER'];
  4357. }
  4358. if (isset($altCfg['MEMCACHED_PORT'])) {
  4359. $memcachedPort = $altCfg['MEMCACHED_PORT'];
  4360. }
  4361. $memcached = new Memcached();
  4362. $memcached->addServer($memcachedHost, $memcachedPort);
  4363. $rawStats = $memcached->getStats();
  4364. $cells = wf_TableCell(__('Parameter'));
  4365. $cells .= wf_TableCell(__('Value'));
  4366. $rows = wf_TableRow($cells, 'row1');
  4367. if (!empty($rawStats)) {
  4368. if (isset($rawStats[$memcachedHost . ':' . $memcachedPort])) {
  4369. foreach ($rawStats[$memcachedHost . ':' . $memcachedPort] as $io => $each) {
  4370. $cells = wf_TableCell($io);
  4371. $cells .= wf_TableCell($each);
  4372. $rows .= wf_TableRow($cells, 'row3');
  4373. }
  4374. //cache efficiency calc
  4375. if ((isset($rawStats[$memcachedHost . ':' . $memcachedPort]['get_hits'])) and (isset($rawStats[$memcachedHost . ':' . $memcachedPort]['get_misses']))) {
  4376. $cacheHits = $rawStats[$memcachedHost . ':' . $memcachedPort]['get_hits'];
  4377. $cacheMisses = $rawStats[$memcachedHost . ':' . $memcachedPort]['get_misses'];
  4378. $cacheTotal = $cacheHits + $cacheMisses;
  4379. $messages = new UbillingMessageHelper();
  4380. $cacheEfficiency = $messages->getStyledMessage(__('Cache efficiency') . ': ' . zb_PercentValue($cacheTotal, $cacheHits) . '%', 'success');
  4381. }
  4382. }
  4383. }
  4384. $result .= wf_TableBody($rows, '100%', 0, '');
  4385. $result .= $cacheEfficiency;
  4386. return ($result);
  4387. }
  4388. /**
  4389. * Returns redis usage stats
  4390. *
  4391. * @global object $ubillingConfig
  4392. * @return string
  4393. */
  4394. function web_RedisRenderStats() {
  4395. global $ubillingConfig;
  4396. $altCfg = $ubillingConfig->getAlter();
  4397. $result = '';
  4398. $cacheEfficiency = '';
  4399. $redisHost = 'localhost';
  4400. $redisdPort = 6379;
  4401. if (isset($altCfg['REDIS_SERVER'])) {
  4402. $redisHost = $altCfg['REDIS_SERVER'];
  4403. }
  4404. if (isset($altCfg['REDIS_PORT'])) {
  4405. $redisdPort = $altCfg['REDIS_PORT'];
  4406. }
  4407. $redis = new Redis();
  4408. $redis->connect($redisHost, $redisdPort);
  4409. $rawStats = $redis->info();
  4410. $cells = wf_TableCell(__('Parameter'));
  4411. $cells .= wf_TableCell(__('Value'));
  4412. $rows = wf_TableRow($cells, 'row1');
  4413. if (!empty($rawStats)) {
  4414. foreach ($rawStats as $param => $value) {
  4415. $cells = wf_TableCell($param);
  4416. $cells .= wf_TableCell($value);
  4417. $rows .= wf_TableRow($cells, 'row3');
  4418. }
  4419. //cache efficiency calc
  4420. if ((isset($rawStats['keyspace_hits'])) and (isset($rawStats['keyspace_misses']))) {
  4421. $cacheHits = $rawStats['keyspace_hits'];
  4422. $cacheMisses = $rawStats['keyspace_misses'];
  4423. $cacheTotal = $cacheHits + $cacheMisses;
  4424. $messages = new UbillingMessageHelper();
  4425. $cacheEfficiency = $messages->getStyledMessage(__('Cache efficiency') . ': ' . zb_PercentValue($cacheTotal, $cacheHits) . '%', 'success');
  4426. }
  4427. }
  4428. $result .= wf_TableBody($rows, '100%', 0, '');
  4429. $result .= $cacheEfficiency;
  4430. return ($result);
  4431. }
  4432. /**
  4433. * Calculates percent value
  4434. *
  4435. * @param float $sum
  4436. * @param float $percent
  4437. *
  4438. * @return float
  4439. */
  4440. function zb_Percent($sum, $percent) {
  4441. // и не надо ржать, я реально не могу запомнить чего куда делить и умножать
  4442. $result = $percent / 100 * $sum;
  4443. return ($result);
  4444. }
  4445. /**
  4446. * Counts percentage between two values
  4447. *
  4448. * @param float $valueTotal
  4449. * @param float $value
  4450. *
  4451. * @return float
  4452. */
  4453. function zb_PercentValue($valueTotal, $value) {
  4454. $result = 0;
  4455. if ($valueTotal != 0) {
  4456. $result = round((($value * 100) / $valueTotal), 2);
  4457. }
  4458. return ($result);
  4459. }
  4460. /**
  4461. * Checks is time between some other time ranges?
  4462. *
  4463. * @param string $fromTime start time (format hh:mm OR hh:mm:ss with seconds)
  4464. * @param string $toTime end time
  4465. * @param string $checkTime time to check
  4466. * @param bool $seconds
  4467. *
  4468. * @return bool
  4469. */
  4470. function zb_isTimeBetween($fromTime, $toTime, $checkTime, $seconds = false) {
  4471. if ($seconds) {
  4472. $formatPostfix = ':s';
  4473. } else {
  4474. $formatPostfix = '';
  4475. }
  4476. $checkTime = strtotime($checkTime);
  4477. $checkTime = date("H:i" . $formatPostfix, $checkTime);
  4478. $f = DateTime::createFromFormat('!H:i' . $formatPostfix, $fromTime);
  4479. $t = DateTime::createFromFormat('!H:i' . $formatPostfix, $toTime);
  4480. $i = DateTime::createFromFormat('!H:i' . $formatPostfix, $checkTime);
  4481. if ($f > $t) {
  4482. $t->modify('+1 day');
  4483. }
  4484. return ($f <= $i && $i <= $t) || ($f <= $i->modify('+1 day') && $i <= $t);
  4485. }
  4486. /**
  4487. * Checks is date between some other date ranges?
  4488. *
  4489. * @param string $fromDate start date (format Y-m-d)
  4490. * @param string $toDate end date
  4491. * @param string $checkDate date to check
  4492. * @param bool $seconds
  4493. *
  4494. * @return bool
  4495. */
  4496. function zb_isDateBetween($fromDate, $toDate, $checkDate) {
  4497. $result = false;
  4498. $fromDate = strtotime($fromDate);
  4499. $toDate = strtotime($toDate);
  4500. $checkDate = strtotime($checkDate);
  4501. $checkDate = date("Y-m-d", $checkDate);
  4502. $checkDate = strtotime($checkDate);
  4503. if ($checkDate >= $fromDate and $checkDate <= $toDate) {
  4504. $result = true;
  4505. }
  4506. return ($result);
  4507. }
  4508. /**
  4509. * Renders time duration in seconds into formatted human-readable view
  4510. *
  4511. * @param int $seconds
  4512. *
  4513. * @return string
  4514. */
  4515. function zb_formatTime($seconds) {
  4516. $init = $seconds;
  4517. $days = floor($seconds / 86400);
  4518. $hours = floor($seconds / 3600);
  4519. $minutes = floor(($seconds / 60) % 60);
  4520. $seconds = $seconds % 60;
  4521. if ($init < 3600) {
  4522. //less than 1 hour
  4523. if ($init < 60) {
  4524. //less than minute
  4525. $result = $seconds . ' ' . __('sec.');
  4526. } else {
  4527. //more than one minute
  4528. $result = $minutes . ' ' . __('minutes') . ' ' . $seconds . ' ' . __('seconds');
  4529. }
  4530. } else {
  4531. if ($init < 86400) {
  4532. //more than hour
  4533. $result = $hours . ' ' . __('hour') . ' ' . $minutes . ' ' . __('minutes') . ' ' . $seconds . ' ' . __('seconds');
  4534. } else {
  4535. $hoursLeft = $hours - ($days * 24);
  4536. $result = $days . ' ' . __('days') . ' ' . $hoursLeft . ' ' . __('hour') . ' ' . $minutes . ' ' . __('minutes') . ' ' . $seconds . ' ' . __('seconds');
  4537. }
  4538. }
  4539. return ($result);
  4540. }
  4541. /**
  4542. * Renders time duration in seconds into formatted human-readable view in days
  4543. *
  4544. * @param int $seconds
  4545. *
  4546. * @return string
  4547. */
  4548. function zb_formatTimeDays($seconds) {
  4549. $init = $seconds;
  4550. $days = floor($seconds / 86400);
  4551. if ($init >= 86400) {
  4552. $result = $days . ' ' . __('days');
  4553. } else {
  4554. if ($init > 0) {
  4555. $result = '0 ' . __('days');
  4556. } else {
  4557. $result = $days . ' ' . __('days');
  4558. }
  4559. }
  4560. return ($result);
  4561. }
  4562. /**
  4563. * Renders list of loaded modules
  4564. *
  4565. * @global object $system
  4566. *
  4567. * @return string
  4568. */
  4569. function zb_ListLoadedModules() {
  4570. $result = '';
  4571. $moduleCount = 0;
  4572. $rightsCount = 0;
  4573. global $system;
  4574. $cells = wf_TableCell(__('Module'));
  4575. $cells .= wf_TableCell(__('Author'));
  4576. $cells .= wf_TableCell(__('Rights generated'));
  4577. $rows = wf_TableRow($cells, 'row1');
  4578. foreach ($system->modules as $type => $modules) {
  4579. if ($type == 'main') {
  4580. foreach ($modules as $module => $moduledata) {
  4581. $moduleRights = '';
  4582. if (!empty($moduledata['rights'])) {
  4583. foreach ($moduledata['rights'] as $right => $rightdesc) {
  4584. $moduleRights .= ' ' . wf_tag('abbr', false, '', 'title="' . $rightdesc . '"') . $right . wf_tag('abbr', true) . ',';
  4585. $rightsCount++;
  4586. }
  4587. $moduleRights = zb_CutEnd($moduleRights);
  4588. }
  4589. $cells = wf_TableCell($moduledata['title']);
  4590. $cells .= wf_TableCell($moduledata['copyright']);
  4591. $cells .= wf_TableCell($moduleRights);
  4592. $rows .= wf_TableRow($cells, 'row3');
  4593. $moduleCount++;
  4594. }
  4595. }
  4596. }
  4597. $result = wf_TableBody($rows, '100%', 0, 'sortable');
  4598. $result .= __('Total') . ': ' . $moduleCount . wf_tag('br');
  4599. $result .= __('Rights generated') . ': ' . $rightsCount;
  4600. return ($result);
  4601. }
  4602. /**
  4603. * Returns current cache info in human readable view with ajax controls
  4604. *
  4605. * @return string
  4606. */
  4607. function zb_ListCacheInformRenderContainer() {
  4608. global $ubillingConfig;
  4609. $alterconf = $ubillingConfig->getAlter();
  4610. $messages = new UbillingMessageHelper();
  4611. $result = '';
  4612. $result .= wf_AjaxLoader();
  4613. $result .= wf_AjaxLink('?module=report_sysload&ajaxcacheinfo=true', wf_img('skins/icon_cache.png') . ' ' . __('Cache information'), 'cachconteiner', false, 'ubButton');
  4614. if ($alterconf['UBCACHE_STORAGE'] == 'memcached') {
  4615. $result .= wf_AjaxLink('?module=report_sysload&ajaxmemcachedstats=true', wf_img_sized('skins/icon_stats.gif', '', 16, 16) . ' ' . __('Stats') . ' ' . __('Memcached'), 'cachconteiner', false, 'ubButton');
  4616. }
  4617. if ($alterconf['UBCACHE_STORAGE'] == 'redis') {
  4618. $result .= wf_AjaxLink('?module=report_sysload&ajaxredisstats=true', wf_img_sized('skins/icon_stats.gif', '', 16, 16) . ' ' . __('Stats') . ' ' . __('Redis'), 'cachconteiner', false, 'ubButton');
  4619. }
  4620. $result .= wf_AjaxLink('?module=report_sysload&ajaxcachedata=true', wf_img('skins/shovel.png') . ' ' . __('Cache data'), 'cachconteiner', false, 'ubButton');
  4621. $result .= wf_AjaxLink('?module=report_sysload&ajaxcacheclear=true', wf_img('skins/icon_cleanup.png') . ' ' . __('Clear all cache'), 'cachconteiner', true, 'ubButton');
  4622. $result .= $messages->getStyledMessage(__('Using system caching engine storage') . ': ' . wf_tag('b') . $alterconf['UBCACHE_STORAGE'] . wf_tag('b', true), 'info');
  4623. $result .= wf_tag('br');
  4624. $result .= wf_tag('table', false, 'sortable', 'width="100%" border="0" id="cachconteiner"') . zb_ListCacheInform() . wf_tag('table', true);
  4625. return ($result);
  4626. }
  4627. /**
  4628. * Renders cache data as auto-open modal dialog
  4629. *
  4630. * @param string $dataKey
  4631. *
  4632. * @return string
  4633. */
  4634. function zb_CacheInformKeyView($dataKey) {
  4635. $result = '';
  4636. $cache = new UbillingCache();
  4637. $allCache = $cache->getAllcache(true);
  4638. if (!empty($allCache)) {
  4639. foreach ($allCache as $io => $each) {
  4640. if ($each['key'] == $dataKey) {
  4641. $readableData = print_r($each['value'], true);
  4642. $value = wf_tag('pre') . htmlspecialchars($readableData) . wf_tag('pre', true);
  4643. $result .= wf_modalOpened(__('Cache information') . ': ' . $dataKey, $value, '800', '600');
  4644. }
  4645. }
  4646. }
  4647. return ($result);
  4648. }
  4649. /**
  4650. * Renders list of cache data
  4651. *
  4652. * @global object $system
  4653. *
  4654. * @param string $param
  4655. *
  4656. * @return string
  4657. */
  4658. function zb_ListCacheInform($param = '') {
  4659. $cache = new UbillingCache();
  4660. $messages = new UbillingMessageHelper();
  4661. ($param == 'clear') ? $cache->deleteAllcache() : '';
  4662. $data = (ispos($param, 'data')) ? $cache->getAllcache($param) : $cache->getAllcache();
  4663. $result = '';
  4664. if (!empty($data) and $param != 'clear') {
  4665. $cells = wf_TableCell(__('ID'));
  4666. $cells .= wf_TableCell(__('Key'));
  4667. if (ispos($param, 'data')) {
  4668. $cells .= wf_TableCell(__('Entries'));
  4669. $cells .= wf_TableCell(__('Data'));
  4670. }
  4671. $rows = wf_TableRow($cells, 'row1');
  4672. foreach ($data as $id => $key) {
  4673. $cells = wf_TableCell($id);
  4674. if (ispos($param, 'data')) {
  4675. $cells .= wf_TableCell($key['key'], '', '', 'sorttable_customkey="' . $id . '"');
  4676. if (is_array($key['value'])) { // needed to prevent e_warnings on PHP 7.3
  4677. $dataCount = sizeof($key['value']);
  4678. } else {
  4679. $dataCount = strlen($key['value']);
  4680. }
  4681. $readableData = print_r($key['value'], true);
  4682. $dataSize = stg_convert_size(strlen($readableData));
  4683. $cells .= wf_TableCell($dataCount . ' ~ ' . $dataSize);
  4684. $keyActions = '';
  4685. $viewContainerId = 'aj_viewcachekey' . $key['key'];
  4686. $viewUrl = '?module=report_sysload&datacachekeyview=' . $key['key'];
  4687. $viewAjLink = wf_AjaxLink($viewUrl, wf_img_sized('skins/icon_search_small.gif', '', '10') . ' ' . __('Cache data'), $viewContainerId, false, 'ubButton');
  4688. $viewControls = $viewAjLink;
  4689. $ajDeleteContainerId = 'aj_deletecachekey' . $key['key'];
  4690. $deleteUrl = '?module=report_sysload&deletecachekey=' . $key['key'];
  4691. $deleteControls = wf_AjaxLink($deleteUrl, wf_img_sized('skins/icon_del.gif', '', '10') . ' ' . __('Delete'), $ajDeleteContainerId, false, 'ubButton');
  4692. $keyActions .= wf_AjaxContainer($ajDeleteContainerId, '', $deleteControls . $viewControls);
  4693. $keyActions .= wf_AjaxContainerSpan($viewContainerId, '');
  4694. $cells .= wf_TableCell($keyActions);
  4695. } else {
  4696. $cells .= wf_TableCell($key, '', '', 'sorttable_customkey = "' . $id . '"');
  4697. }
  4698. $rows .= wf_TableRow($cells, 'row3');
  4699. }
  4700. $result .= $rows;
  4701. } elseif (empty($data) and $param == 'clear') {
  4702. $result .= $messages->getStyledMessage(__('Cache cleared'), 'success');
  4703. }
  4704. return ($result);
  4705. }
  4706. /**
  4707. * Deletes some entry key data from cache
  4708. *
  4709. * @param string $key
  4710. *
  4711. * @return string
  4712. */
  4713. function zb_CacheKeyDestroy($key) {
  4714. $result = '';
  4715. $messages = new UbillingMessageHelper();
  4716. if (!empty($key)) {
  4717. $cache = new UbillingCache();
  4718. $key = str_replace($cache::CACHE_PREFIX, '', $key);
  4719. $cache->delete($key);
  4720. $result .= $messages->getStyledMessage(__('Deleted'), 'warning');
  4721. }
  4722. return ($result);
  4723. }
  4724. /**
  4725. * Downloads and unpacks phpsysinfo distro
  4726. *
  4727. * @global object $ubillingConfig
  4728. *
  4729. * @return void
  4730. */
  4731. function zb_InstallPhpsysinfo() {
  4732. global $ubillingConfig;
  4733. $billCfg = $ubillingConfig->getBilling();
  4734. $phpSysInfoDir = $billCfg['PHPSYSINFO'];
  4735. if (!empty($phpSysInfoDir)) {
  4736. if (cfr('ROOT')) {
  4737. $upd = new UbillingUpdateStuff();
  4738. $upd->downloadRemoteFile('http://ubilling.net.ua/packages/phpsysinfo.tar.gz', 'exports/', 'phpsysinfo.tar.gz');
  4739. $upd->extractTgz('exports/phpsysinfo.tar.gz', MODULES_DOWNLOADABLE . $phpSysInfoDir);
  4740. }
  4741. }
  4742. }
  4743. /**
  4744. * Downloads and unpacks xhprof distro
  4745. *
  4746. * @return void
  4747. */
  4748. function zb_InstallXhprof() {
  4749. if (cfr('ROOT')) {
  4750. $upd = new UbillingUpdateStuff();
  4751. $upd->downloadRemoteFile('http://ubilling.net.ua/packages/xhprof.tar.gz', 'exports/', 'xhprof.tar.gz');
  4752. $upd->extractTgz('exports/xhprof.tar.gz', MODULES_DOWNLOADABLE . 'xhprof/');
  4753. }
  4754. }
  4755. /**
  4756. * Sorting array of arrays by some field in ascending or descending order
  4757. * Returns sorted array
  4758. *
  4759. * @param $data - array to sort
  4760. * @param $field - field to sort by
  4761. * @param bool $desc - sorting order
  4762. *
  4763. * Source code: https://www.the-art-of-web.com/php/sortarray/#section_8
  4764. *
  4765. * @return mixed
  4766. */
  4767. function zb_sortArray($data, $field, $desc = false) {
  4768. if (!is_array($field)) {
  4769. $field = array($field);
  4770. }
  4771. usort($data, function ($a, $b) use ($field, $desc) {
  4772. $retval = 0;
  4773. foreach ($field as $fieldname) {
  4774. if ($desc) {
  4775. if ($retval == 0)
  4776. $retval = strnatcmp($b[$fieldname], $a[$fieldname]);
  4777. } else {
  4778. if ($retval == 0)
  4779. $retval = strnatcmp($a[$fieldname], $b[$fieldname]);
  4780. }
  4781. }
  4782. return $retval;
  4783. });
  4784. return $data;
  4785. }
  4786. /**
  4787. * Returns an array of SMS services represented like: id => name
  4788. * with the default service on top of it
  4789. *
  4790. * @return array
  4791. */
  4792. function zb_getSMSServicesList() {
  4793. $result = array();
  4794. $smsServicesList = array();
  4795. $defaultSmsServiceId = 0;
  4796. $defaultSmsServiceName = '';
  4797. $query = "SELECT * FROM `sms_services`;";
  4798. $result = simple_queryall($query);
  4799. if (!empty($result)) {
  4800. foreach ($result as $index => $record) {
  4801. if ($record['default_service']) {
  4802. $defaultSmsServiceId = $record['id'];
  4803. $defaultSmsServiceName = $record['name'] . ' (' . __('by default') . ')';
  4804. continue;
  4805. }
  4806. $smsServicesList[$record['id']] = $record['name'];
  4807. }
  4808. if (!empty($defaultSmsServiceId) and !empty($defaultSmsServiceName)) {
  4809. $smsServicesList = array($defaultSmsServiceId => $defaultSmsServiceName) + $smsServicesList;
  4810. }
  4811. }
  4812. return $smsServicesList;
  4813. }
  4814. /**
  4815. * Returns SMS service name by it's ID. If empty ID parameter returns the name of the default SMS service.
  4816. * For big message sets it's strongly recommended to use SMSDirections class instead
  4817. *
  4818. * @param int $smsServiceId
  4819. *
  4820. * @return string
  4821. */
  4822. function zb_getSMSServiceNameByID($smsServiceId = 0) {
  4823. $smsServiceName = '';
  4824. $result = array();
  4825. if (empty($smsServiceId)) {
  4826. $Query = "SELECT * FROM `sms_services` WHERE `default_service` > 0;";
  4827. } else {
  4828. $Query = "SELECT * FROM `sms_services` WHERE `id` = " . $smsServiceId . ";";
  4829. }
  4830. $result = simple_queryall($Query);
  4831. if (!empty($result)) {
  4832. $smsServiceName = $result[0]['name'];
  4833. }
  4834. return $smsServiceName;
  4835. }
  4836. /**
  4837. * Returns array containing user's preferred SMS service in form of
  4838. * [0] => [id]
  4839. * [1] => [name]
  4840. *
  4841. * @param $userLogin
  4842. *
  4843. * @return array
  4844. */
  4845. function zb_getUsersPreferredSMSService($userLogin) {
  4846. $smsServiceIdName = array('', '');
  4847. $query = "SELECT * FROM `sms_services_relations` WHERE `user_login` = '" . $userLogin . "';";
  4848. $result = simple_queryall($query);
  4849. if (!empty($result)) {
  4850. $smsServiceIdName[0] = $result[0]['sms_srv_id'];
  4851. }
  4852. $smsServiceIdName[1] = zb_getSMSServiceNameByID($smsServiceIdName[0]);
  4853. return $smsServiceIdName;
  4854. }
  4855. /**
  4856. * Inits ghost mode for some administrator login
  4857. *
  4858. * @param string $adminLogin
  4859. *
  4860. * @return void
  4861. */
  4862. function zb_InitGhostMode($adminLogin) {
  4863. global $system;
  4864. if (file_exists(USERS_PATH . $adminLogin)) {
  4865. $userData = $system->getUserData($adminLogin);
  4866. if (!empty($userData)) {
  4867. $myLogin = whoami();
  4868. $myData = $system->getUserData($myLogin);
  4869. //current login data is used for ghost mode identification
  4870. setcookie('ghost_user', $myLogin . ':' . $myData['password'], null);
  4871. $_COOKIE['ghost_user'] = $myLogin . ':' . $myData['password'];
  4872. //login of another admin
  4873. rcms_log_put('Notification', $myLogin, 'Ghost logged in as ' . $adminLogin);
  4874. log_register('GHOSTMODE {' . $myLogin . '} LOGIN AS {' . $adminLogin . '}');
  4875. setcookie('ubilling_user', $adminLogin . ':' . $userData['password'], null);
  4876. $_COOKIE['ubilling_user'] = $adminLogin . ':' . $userData['password'];
  4877. }
  4878. }
  4879. }
  4880. /**
  4881. * Cleanups backups directory dumps older than X days encoded in filename.
  4882. *
  4883. * @param int $maxAge
  4884. *
  4885. * @return void
  4886. */
  4887. function zb_BackupsRotate($maxAge) {
  4888. $maxAge = vf($maxAge, 3);
  4889. if ($maxAge) {
  4890. if (is_numeric($maxAge)) {
  4891. $curTimeStamp = curdate();
  4892. $curTimeStamp = strtotime($curTimeStamp);
  4893. $cleanupTimeStamp = $curTimeStamp - ($maxAge * 86400); // Option is in days
  4894. $backupsDirectory = DATA_PATH . 'backups/sql/';
  4895. $backupsPrefix = 'ubilling-';
  4896. $backupsExtension = '.sql';
  4897. $allBackups = rcms_scandir($backupsDirectory, '*' . $backupsExtension);
  4898. if (!empty($allBackups)) {
  4899. foreach ($allBackups as $io => $eachDump) {
  4900. //trying to extract date from filename
  4901. $cleanName = $eachDump;
  4902. $cleanName = str_replace($backupsPrefix, '', $cleanName);
  4903. $cleanName = str_replace($backupsExtension, '', $cleanName);
  4904. if (ispos($cleanName, '_')) {
  4905. $explode = explode('_', $cleanName);
  4906. $cleanName = $explode[0];
  4907. if (zb_checkDate($cleanName)) {
  4908. $dumpTimeStamp = strtotime($cleanName);
  4909. if ($dumpTimeStamp < $cleanupTimeStamp) {
  4910. $rotateBackupPath = $backupsDirectory . $eachDump;
  4911. rcms_delete_files($rotateBackupPath);
  4912. log_register('BACKUP ROTATE `' . $rotateBackupPath . '`');
  4913. }
  4914. }
  4915. }
  4916. }
  4917. }
  4918. }
  4919. }
  4920. }
  4921. /**
  4922. * Performs filtering of tariff name
  4923. *
  4924. * @param string $tariffname
  4925. *
  4926. * @return string
  4927. */
  4928. function zb_TariffNameFilter($tariffname) {
  4929. $tariffname = trim($tariffname);
  4930. $tariffname = preg_replace("#[^a-z0-9A-Z\-_\.]#Uis", '', $tariffname);
  4931. if (strlen($tariffname) > 32) {
  4932. //stargazer dramatically fails on long tariff names
  4933. $tariffname = substr($tariffname, 0, 32);
  4934. }
  4935. return ($tariffname);
  4936. }
  4937. /**
  4938. * Returns Stargazer tariff creation select input options string
  4939. *
  4940. * @param int $t count of selectable options
  4941. * @param int $selected selected option here
  4942. *
  4943. * @return string
  4944. */
  4945. function zb_TariffTimeSelector($t, $selected = false) {
  4946. $result = '';
  4947. $b = '';
  4948. for ($i = 1; $i < $t; ++$i) {
  4949. if ($i < 10) {
  4950. $a = '0';
  4951. } else {
  4952. $a = '';
  4953. }
  4954. if ($selected == @$a . $i) {
  4955. $b = 'SELECTED';
  4956. } else {
  4957. $b = '';
  4958. }
  4959. $result .= wf_tag('option', false, '', $b) . $a . $i . wf_tag('option', true);
  4960. }
  4961. return ($result);
  4962. }
  4963. /**
  4964. * Returns list of available Stargazer tariffs with some controls
  4965. *
  4966. * @global object $ubillingConfig
  4967. *
  4968. * @return string
  4969. */
  4970. function web_TariffLister() {
  4971. $alltariffs = billing_getalltariffs();
  4972. $dbSchema = zb_CheckDbSchema();
  4973. global $ubillingConfig;
  4974. $alter = $ubillingConfig->getAlter();
  4975. $tariffSpeeds = zb_TariffGetAllSpeeds();
  4976. $cells = wf_TableCell(__('Tariff name'));
  4977. $cells .= wf_TableCell(__('Tariff Fee'));
  4978. if ($dbSchema > 0) {
  4979. $cells .= wf_TableCell(__('Period'));
  4980. }
  4981. $cells .= wf_TableCell(__('Speed'));
  4982. $cells .= wf_TableCell(__('Actions'));
  4983. $rows = wf_TableRow($cells, 'row1');
  4984. $result = wf_Link("?module=tariffs&action=new", web_icon_create() . ' ' . __('Create new tariff'), true, 'ubButton');
  4985. if (!empty($alltariffs)) {
  4986. foreach ($alltariffs as $io => $eachtariff) {
  4987. $cells = wf_TableCell($eachtariff['name']);
  4988. $cells .= wf_TableCell($eachtariff['Fee']);
  4989. if ($dbSchema > 0) {
  4990. $cells .= wf_TableCell(__($eachtariff['period']));
  4991. }
  4992. if (isset($tariffSpeeds[$eachtariff['name']])) {
  4993. $speedData = $tariffSpeeds[$eachtariff['name']]['speeddown'] . ' / ' . $tariffSpeeds[$eachtariff['name']]['speedup'];
  4994. } else {
  4995. $speedData = wf_tag('font', false, '', 'color="#bc0000"') . __('Speed is not set') . wf_tag('font', true);
  4996. }
  4997. $cells .= wf_TableCell($speedData);
  4998. $actions = wf_JSAlert("?module=tariffs&action=delete&tariffname=" . $eachtariff['name'], web_delete_icon(), __('Delete') . ' ' . $eachtariff['name'] . '? ' . __('Removing this may lead to irreparable results'));
  4999. $actions .= wf_JSAlert("?module=tariffs&action=edit&tariffname=" . $eachtariff['name'], web_edit_icon(), __('Edit') . ' ' . $eachtariff['name'] . '? ' . __('Are you serious'));
  5000. $actions .= wf_Link('?module=tariffspeeds&tariff=' . $eachtariff['name'], wf_img('skins/icon_speed.gif', __('Edit speed')), false, '');
  5001. $actions .= (isset($alter['SIGNUP_PAYMENTS']) && !empty($alter['SIGNUP_PAYMENTS'])) ? wf_Link('?module=signupprices&tariff=' . $eachtariff['name'], wf_img('skins/icons/register.png', __('Edit signup price')), false, '') : null;
  5002. $cells .= wf_TableCell($actions);
  5003. $rows .= wf_TableRow($cells, 'row5');
  5004. }
  5005. }
  5006. $result .= wf_TableBody($rows, '100%', 0, 'sortable');
  5007. return ($result);
  5008. }
  5009. /**
  5010. * WTF???!!!
  5011. *
  5012. * @param type $a
  5013. * @param type $b
  5014. * @return type
  5015. */
  5016. function zb_tariff_yoba_price($a, $b) {
  5017. if ($a == $b) {
  5018. return $a;
  5019. } else {
  5020. return "$a/$b";
  5021. }
  5022. }
  5023. /**
  5024. * Renders new tariff creation form
  5025. *
  5026. * @global array $dirs
  5027. *
  5028. * @return string
  5029. */
  5030. function web_TariffCreateForm() {
  5031. global $dirs;
  5032. $dbSchema = zb_CheckDbSchema();
  5033. if ($dbSchema > 0) { //stargazer >=2.409
  5034. $availOpts = array('month' => __('Month'), 'day' => __('Day'));
  5035. $periodControls = wf_Selector("options[Period]", $availOpts, __('Period'), @$tariffdata['period'], true);
  5036. $periodControls .= wf_delimiter(0);
  5037. } else {
  5038. $periodControls = '';
  5039. }
  5040. $traffCountOptions = array(
  5041. 'up+down' => 'up+down',
  5042. 'up' => 'up',
  5043. 'down' => 'down',
  5044. 'max' => 'max',
  5045. );
  5046. $result = '';
  5047. $inputs = wf_TextInput('options[TARIFF]', __('Tariff name'), '', true, '20');
  5048. $inputs .= wf_delimiter(0);
  5049. $inputs .= wf_TextInput('options[Fee]', __('Fee'), '0', true, 4, 'finance');
  5050. $inputs .= wf_delimiter(0);
  5051. $inputs .= $periodControls;
  5052. $inputs .= wf_TextInput('options[Free]', __('Prepaid traffic') . ' (' . __('Mb') . ')', '0', true, 3, 'digits');
  5053. $inputs .= wf_delimiter(0);
  5054. $inputs .= wf_Selector('options[TraffType]', $traffCountOptions, __('Counting traffic'), '', true);
  5055. $inputs .= wf_delimiter(0);
  5056. $inputs .= wf_TextInput('options[PassiveCost]', __('Cost of freezing'), '', true, 3, 'finance');
  5057. $inputs .= wf_delimiter(0);
  5058. $inputsDirs = '';
  5059. foreach ($dirs as $dir) {
  5060. $inputsDirs .= wf_tag('fieldset', false);
  5061. $inputsDirs .= wf_tag('legend');
  5062. $inputsDirs .= __('Traffic classes') . ': ' . wf_tag('b') . $dir['rulename'] . wf_tag('b', true);
  5063. $inputsDirs .= wf_tag('legend', true);
  5064. $inputsDirs .= wf_tag('select', false, '', 'id="dhour' . $dir['rulenumber'] . '" name="options[dhour][' . $dir['rulenumber'] . ']"');
  5065. $inputsDirs .= wf_tag('option', false, '', 'SELECTED') . '00' . wf_tag('option', true);
  5066. $inputsDirs .= zb_TariffTimeSelector(24);
  5067. $inputsDirs .= wf_tag('select', true);
  5068. $inputsDirs .= wf_tag('select', false, '', 'id="dmin' . $dir['rulenumber'] . '" name="options[dmin][' . $dir['rulenumber'] . ']"');
  5069. $inputsDirs .= wf_tag('option', false, '', 'SELECTED') . '00' . wf_tag('option', true);
  5070. $inputsDirs .= zb_TariffTimeSelector(60);
  5071. $inputsDirs .= wf_tag('select', true);
  5072. $inputsDirs .= ' (' . __('hours') . '/' . __('minutes') . ') ' . __('Day');
  5073. $inputsDirs .= wf_TextInput('options[PriceDay][' . $dir['rulenumber'] . ']', __('Price day'), '', false, 3);
  5074. $inputsDirs .= wf_TextInput('options[Threshold][' . $dir['rulenumber'] . ']', __('Threshold') . ' (' . __('Mb') . ')', '0', true, 3, 'digits');
  5075. $inputsDirs .= wf_tag('select', false, '', 'id="nhour' . $dir['rulenumber'] . '" name="options[nhour][' . $dir['rulenumber'] . ']"');
  5076. $inputsDirs .= wf_tag('option', false, '', 'SELECTED') . '00' . wf_tag('option', true);
  5077. $inputsDirs .= zb_TariffTimeSelector(24);
  5078. $inputsDirs .= wf_tag('select', true);
  5079. $inputsDirs .= wf_tag('select', false, '', 'id="nmin' . $dir['rulenumber'] . '" name="options[nmin][' . $dir['rulenumber'] . ']"');
  5080. $inputsDirs .= wf_tag('option', false, '', 'SELECTED') . '00' . wf_tag('option', true);
  5081. $inputsDirs .= zb_TariffTimeSelector(60);
  5082. $inputsDirs .= wf_tag('select', true);
  5083. $inputsDirs .= ' (' . __('hours') . '/' . __('minutes') . ') ' . __('Night');
  5084. $inputsDirs .= wf_TextInput('options[PriceNight][' . $dir['rulenumber'] . ']', __('Price night'), '', false, 3);
  5085. $inputsDirs .= wf_CheckInput('options[NoDiscount][' . $dir['rulenumber'] . ']', __('Without threshold'), true, true);
  5086. $inputsDirs .= wf_CheckInput('options[SinglePrice][' . $dir['rulenumber'] . ']', __('Price does not depend on time'), true, true);
  5087. $inputsDirs .= wf_tag('fieldset', true);
  5088. $inputsDirs .= wf_delimiter(0);
  5089. }
  5090. $allInputs = $inputs . $inputsDirs;
  5091. $allInputs .= wf_Submit(__('Create new tariff'));
  5092. $result .= wf_Form('', 'POST', $allInputs, '', '', 'tariff_add');
  5093. return ($result);
  5094. }
  5095. /**
  5096. * Renders existing tariff editing form
  5097. *
  5098. * @global array $dirs
  5099. * @param string $tariffname
  5100. *
  5101. * @return string
  5102. */
  5103. function web_TariffEditForm($tariffname) {
  5104. global $dirs;
  5105. $result = '';
  5106. $tariffdata = billing_gettariff($tariffname);
  5107. if (!empty($tariffdata)) {
  5108. $traffCountOptions = array(
  5109. 'up+down' => 'up+down',
  5110. 'up' => 'up',
  5111. 'down' => 'down',
  5112. 'max' => 'max',
  5113. );
  5114. $dbSchema = zb_CheckDbSchema();
  5115. if ($dbSchema > 0) {
  5116. $availOpts = array('month' => __('Month'), 'day' => __('Day'));
  5117. $periodControls = wf_Selector("options[Period]", $availOpts, __('Period'), $tariffdata['period'], true);
  5118. $periodControls .= wf_delimiter(0);
  5119. } else {
  5120. $periodControls = '';
  5121. }
  5122. $form = '';
  5123. $inputs = '';
  5124. $inputs .= wf_TextInput('options[TARIFF]', __('Tariff name'), $tariffdata['name'], true, 20, '', '', '', 'DISABLED');
  5125. $inputs .= wf_delimiter(0);
  5126. $inputs .= wf_TextInput('options[Fee]', __('Fee'), $tariffdata['Fee'], true, 4, 'finance');
  5127. $inputs .= wf_delimiter(0);
  5128. $inputs .= $periodControls;
  5129. $inputs .= wf_TextInput('options[Free]', __('Prepaid traffic') . ' (' . __('Mb') . ')', $tariffdata['Free'], true, 3, 'digits');
  5130. $inputs .= wf_delimiter(0);
  5131. $inputs .= wf_Selector('options[TraffType]', $traffCountOptions, __('Counting traffic'), $tariffdata['TraffType'], true);
  5132. $inputs .= wf_delimiter(0);
  5133. $inputs .= wf_TextInput('options[PassiveCost]', __('Cost of freezing'), $tariffdata['PassiveCost'], true, 3, 'finance');
  5134. $inputs .= wf_delimiter(0);
  5135. $inputsDirs = '';
  5136. foreach ($dirs as $dir) {
  5137. $inputsDirs .= wf_tag('fieldset', false);
  5138. $inputsDirs .= wf_tag('legend');
  5139. $inputsDirs .= __('Traffic classes') . ': ' . wf_tag('b') . $dir['rulename'] . wf_tag('b', true);
  5140. $inputsDirs .= wf_tag('legend', true);
  5141. $rulenumber = $dir['rulenumber'];
  5142. $arrTime = explode('-', $tariffdata["Time" . $rulenumber]);
  5143. $day = explode(':', $arrTime[0]);
  5144. $night = explode(':', $arrTime[1]);
  5145. $tariffdata['Time'][$rulenumber]['Dmin'] = $day[1];
  5146. $tariffdata['Time'][$rulenumber]['Dhour'] = $day[0];
  5147. $tariffdata['Time'][$rulenumber]['Nmin'] = $night[1];
  5148. $tariffdata['Time'][$rulenumber]['Nhour'] = $night[0];
  5149. $inputsDirs .= wf_tag('select', false, '', 'id="dhour' . $dir['rulenumber'] . '" name="options[dhour][' . $dir['rulenumber'] . ']"');
  5150. $inputsDirs .= wf_tag('option', false, '', '') . '00' . wf_tag('option', true);
  5151. $inputsDirs .= zb_TariffTimeSelector(24, $tariffdata['Time'][$dir['rulenumber']]['Dhour']);
  5152. $inputsDirs .= wf_tag('select', true);
  5153. $inputsDirs .= wf_tag('select', false, '', 'id="dmin' . $dir['rulenumber'] . '" name="options[dmin][' . $dir['rulenumber'] . ']"');
  5154. $inputsDirs .= wf_tag('option', false, '', '') . '00' . wf_tag('option', true);
  5155. $inputsDirs .= zb_TariffTimeSelector(60, $tariffdata['Time'][$dir['rulenumber']]['Dmin']);
  5156. $inputsDirs .= wf_tag('select', true);
  5157. $inputsDirs .= ' (' . __('hours') . '/' . __('minutes') . ') ' . __('Day');
  5158. $inputsDirs .= wf_TextInput('options[PriceDay][' . $dir['rulenumber'] . ']', __('Price day'), zb_tariff_yoba_price($tariffdata["PriceDayA" . $dir['rulenumber']], $tariffdata["PriceDayB" . $dir['rulenumber']]), false, 3);
  5159. $inputsDirs .= wf_TextInput('options[Threshold][' . $dir['rulenumber'] . ']', __('Threshold') . ' (' . __('Mb') . ')', $tariffdata["Threshold$dir[rulenumber]"], true, 3, 'digits');
  5160. $inputsDirs .= wf_tag('select', false, '', 'id="nhour' . $dir['rulenumber'] . '" name="options[nhour][' . $dir['rulenumber'] . ']"');
  5161. $inputsDirs .= wf_tag('option', false, '', '') . '00' . wf_tag('option', true);
  5162. $inputsDirs .= zb_TariffTimeSelector(24, $tariffdata['Time'][$dir['rulenumber']]['Nhour']);
  5163. $inputsDirs .= wf_tag('select', true);
  5164. $inputsDirs .= wf_tag('select', false, '', 'id="nmin' . $dir['rulenumber'] . '" name="options[nmin][' . $dir['rulenumber'] . ']"');
  5165. $inputsDirs .= wf_tag('option', false, '', '') . '00' . wf_tag('option', true);
  5166. $inputsDirs .= zb_TariffTimeSelector(60, $tariffdata['Time'][$dir['rulenumber']]['Nmin']);
  5167. $inputsDirs .= wf_tag('select', true);
  5168. $inputsDirs .= ' (' . __('hours') . '/' . __('minutes') . ') ' . __('Night');
  5169. $inputsDirs .= wf_TextInput('options[PriceNight][' . $dir['rulenumber'] . ']', __('Price night'), zb_tariff_yoba_price($tariffdata["PriceNightA$dir[rulenumber]"], $tariffdata["PriceNightB$dir[rulenumber]"]), false, 3);
  5170. $inputsDirs .= wf_CheckInput('options[NoDiscount][' . $dir['rulenumber'] . ']', __('Without threshold'), true, $tariffdata["NoDiscount" . $rulenumber]);
  5171. $inputsDirs .= wf_CheckInput('options[SinglePrice][' . $dir['rulenumber'] . ']', __('Price does not depend on time'), true, $tariffdata["SinglePrice" . $rulenumber]);
  5172. $inputsDirs .= wf_tag('fieldset', true);
  5173. $inputsDirs .= wf_delimiter(0);
  5174. }
  5175. $allInputs = $inputs . $inputsDirs;
  5176. $allInputs .= wf_Submit(__('Save'));
  5177. $result .= wf_Form('', 'POST', $allInputs, '', '', 'save');
  5178. } else {
  5179. $messages = new UbillingMessageHelper();
  5180. $result .= $messages->getStyledMessage(__('Something went wrong') . ': FATAL_TARIFF_NOT_EXISTS', 'error');
  5181. }
  5182. return ($result);
  5183. }
  5184. /**
  5185. * Returns switch problem from zabbix in profile form
  5186. *
  5187. * @param string $login
  5188. * @return string
  5189. */
  5190. function web_ProfileSwitchZabbixProblem($login) {
  5191. $result = '';
  5192. $login = mysql_real_escape_string($login);
  5193. $query = "SELECT `ip` FROM `switchportassign` LEFT JOIN `switches` ON (switchid=`switches`.`id`) WHERE login = '" . $login . "' LIMIT 1";
  5194. //getting switch IP
  5195. $swIP = simple_query($query);
  5196. if (!empty($swIP)) {
  5197. $allProblems = getZabbixProblems($swIP['ip']);
  5198. if (!empty($allProblems)) {
  5199. $cells = wf_TableCell(wf_tag('b', false) . __('Problem') . wf_tag('b', true), '30%', 'row2');
  5200. $cells .= wf_TableCell(wf_tag('b', false) . __('Start date') . wf_tag('b', true), '', 'row2');
  5201. $cells .= wf_TableCell(wf_tag('b', false) . __('Notes') . wf_tag('b', true), '', 'row2');
  5202. $rows = wf_TableRow($cells, 'row3');
  5203. foreach ($allProblems as $io => $problemData) {
  5204. // Colorized problem
  5205. if ($problemData['severity'] == 5) {
  5206. $problemColor = wf_tag('font', false, '', 'color="#8B0000"') . wf_tag('b', false);
  5207. $problemColorEnd = wf_tag('b', true) . wf_tag('font', true);
  5208. } elseif ($problemData['severity'] == 4) {
  5209. $problemColor = wf_tag('font', false, '', 'color="#FF0000"') . wf_tag('b', false);
  5210. $problemColorEnd = wf_tag('b', true) . wf_tag('font', true);
  5211. } elseif ($problemData['severity'] == 3) {
  5212. $problemColor = wf_tag('font', false, '', 'color="#00008B"') . wf_tag('b', false);
  5213. $problemColorEnd = wf_tag('b', true) . wf_tag('font', true);
  5214. } elseif ($problemData['severity'] == 2) {
  5215. $problemColor = wf_tag('font', false, '', 'color="#4682B4"') . wf_tag('b', false);
  5216. $problemColorEnd = wf_tag('b', true) . wf_tag('font', true);
  5217. } elseif ($problemData['severity'] == 1) {
  5218. $problemColor = wf_tag('font', false, '', 'color="#7499FF"') . wf_tag('b', false);
  5219. $problemColorEnd = wf_tag('b', true) . wf_tag('font', true);
  5220. } else {
  5221. $problemColor = wf_tag('b', false);
  5222. $problemColorEnd = wf_tag('b', true);
  5223. }
  5224. $acknowledges = $problemData['acknowledges'];
  5225. $acknowledgesMessages = array_column($acknowledges, 'message');
  5226. $cells = wf_TableCell($problemColor . __($problemData['name']) . $problemColorEnd, '30%');
  5227. $cells .= wf_TableCell(date('Y-m-d H:i:s', $problemData['clock']));
  5228. $cells .= wf_TableCell(implode(wf_tag('br'), $acknowledgesMessages));
  5229. $rows .= wf_TableRow($cells, 'row4');
  5230. }
  5231. $result = wf_TableBody($rows, '100%', '0');
  5232. }
  5233. }
  5234. return ($result);
  5235. }
  5236. /**
  5237. * Inserts some element into specific array index position
  5238. *
  5239. * @param array $array
  5240. * @param int|string $position
  5241. * @param mixed $insert
  5242. */
  5243. function zb_array_insert(&$array, $position, $insert) {
  5244. if (is_int($position)) {
  5245. array_splice($array, $position, 0, $insert);
  5246. } else {
  5247. $pos = array_search($position, array_keys($array));
  5248. $array = array_merge(
  5249. array_slice($array, 0, $pos),
  5250. $insert,
  5251. array_slice($array, $pos)
  5252. );
  5253. }
  5254. }
  5255. /**
  5256. * Returns generic printable report content
  5257. *
  5258. * @param string $title report title
  5259. * @param string $data report data to printable transform
  5260. *
  5261. * @return void
  5262. */
  5263. function zb_ReportPrintable($title, $data) {
  5264. $style = file_get_contents(CONFIG_PATH . "ukvprintable.css");
  5265. $header = wf_tag('!DOCTYPE', false, '', 'html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"');
  5266. $header .= wf_tag('html', false, '', 'xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru"');
  5267. $header .= wf_tag('head', false);
  5268. $header .= wf_tag('title') . $title . wf_tag('title', true);
  5269. $header .= wf_tag('meta', false, '', 'http-equiv="Content-Type" content="text/html; charset=UTF-8" /');
  5270. $header .= wf_tag('style', false, '', 'type="text/css"');
  5271. $header .= $style;
  5272. $header .= wf_tag('style', true);
  5273. $header .= wf_tag('script', false, '', 'src="modules/jsc/sorttable.js" language="javascript"') . wf_tag('script', true);
  5274. $header .= wf_tag('head', true);
  5275. $header .= wf_tag('body', false);
  5276. $footer = wf_tag('body', true);
  5277. $footer .= wf_tag('html', true);
  5278. $title = (!empty($title)) ? wf_tag('h2') . $title . wf_tag('h2', true) : '';
  5279. $data = $header . $title . $data . $footer;
  5280. die($data);
  5281. }
  5282. /**
  5283. * Renders EasyFreeze form and process some requests
  5284. *
  5285. * @param string $login
  5286. *
  5287. * @return string
  5288. */
  5289. function web_EasyFreezeForm($login) {
  5290. $result = '';
  5291. $dateFromPreset = curdate();
  5292. $dateToPreset = date("Y-m-t");
  5293. $inputs = '<!--ugly hack to prevent datepicker autoopen -->';
  5294. $inputs .= wf_TextInput('omghack', '', '', false, '', '', '', '', 'style="width: 0; height: 0; top: -100px; position: absolute;"');
  5295. $inputs .= wf_HiddenInput('easyfreezeuser', $login);
  5296. $inputs .= __('Date from') . ' ' . wf_DatePickerPreset('easyfreezedatefrom', $dateFromPreset, true) . ' ';
  5297. $inputs .= __('Date to') . ' ' . wf_DatePickerPreset('easyfreezedateto', $dateToPreset, true);
  5298. $inputs .= wf_delimiter(0);
  5299. $inputs .= wf_CheckInput('easyfreezerightnow', __('Freeze user') . ' ' . __('right now'), true, false);
  5300. $inputs .= wf_CheckInput('easyfreezeforever', __('Freeze user') . ' ' . __('forever'), true, false);
  5301. $inputs .= wf_TextInput('easyfreezenote', __('Notes'), '', true, 30);
  5302. $inputs .= wf_delimiter(0);
  5303. $inputs .= wf_Submit(__('Freeze user'));
  5304. $result = wf_Form('', 'POST', $inputs, 'glamour');
  5305. return ($result);
  5306. }
  5307. /**
  5308. * Catches and do some processing of easyfreeze requests
  5309. *
  5310. * @global object $billing
  5311. *
  5312. * @return void/string on error
  5313. */
  5314. function zb_EasyFreezeController() {
  5315. $result = '';
  5316. //freezing processing
  5317. if (ubRouting::checkPost(array('easyfreezeuser', 'easyfreezedatefrom', 'easyfreezedateto'))) {
  5318. global $billing;
  5319. $scheduler = new DealWithIt();
  5320. $loginToFreeze = ubRouting::post('easyfreezeuser');
  5321. $freezingNote = 'EASYFREEZE:' . ubRouting::post('easyfreezenote');
  5322. $dateFrom = ubRouting::post('easyfreezedatefrom');
  5323. $dateTo = ubRouting::post('easyfreezedateto');
  5324. if (zb_checkDate($dateFrom) and zb_checkDate($dateTo)) {
  5325. //freezing
  5326. if (ubRouting::checkPost('easyfreezerightnow')) {
  5327. //just freeze user right now
  5328. $billing->setpassive($loginToFreeze, 1);
  5329. log_register('CHANGE Passive (' . $loginToFreeze . ') ON 1 NOTE `' . $freezingNote . '`');
  5330. } else {
  5331. //create new freezing schedule
  5332. $scheduler->createTask($dateFrom, $loginToFreeze, 'freeze', '', $freezingNote);
  5333. }
  5334. //unfreezing schedule if not forever
  5335. if (!ubRouting::checkPost('easyfreezeforever')) {
  5336. $scheduler->createTask($dateTo, $loginToFreeze, 'unfreeze', '', $freezingNote);
  5337. }
  5338. //refresh profile
  5339. ubRouting::nav(UserProfile::URL_PROFILE . $loginToFreeze);
  5340. } else {
  5341. $result .= __('Wrong date format');
  5342. }
  5343. }
  5344. return ($result);
  5345. }
  5346. /**
  5347. * Convert a string to an array as str_split but multibyte-safe.
  5348. *
  5349. * @param string $string
  5350. * @param int $length
  5351. *
  5352. * @return array
  5353. */
  5354. function zb_split_mb($string, $length = 1) {
  5355. $result = preg_split('~~u', $string, -1, PREG_SPLIT_NO_EMPTY);
  5356. if ($length > 1) {
  5357. $chunks = array_chunk($result, $length);
  5358. foreach ($chunks as $i => $chunk) {
  5359. $chunks[$i] = join('', (array) $chunk);
  5360. }
  5361. $result = $chunks;
  5362. }
  5363. return ($result);
  5364. }
  5365. /**
  5366. * Tries to re-format incorrectly inputted cell number to bring it to the correct form
  5367. *
  5368. * @param $number
  5369. *
  5370. * @return bool|mixed|string
  5371. */
  5372. function zb_CleanMobileNumber($number) {
  5373. if (!empty($number) and substr(trim($number), 0, 1) != '+') {
  5374. global $ubillingConfig;
  5375. $prefix = $ubillingConfig->getAlterParam('REMINDER_PREFIX', '');
  5376. $number = trim($number);
  5377. $number = ubRouting::filters($number, 'int');
  5378. $number = SendDog::cutInternationalsFromPhoneNum($number);
  5379. $number = $prefix . $number;
  5380. }
  5381. return ($number);
  5382. }
  5383. /**
  5384. * Returns list of available MultiGen NASes
  5385. *
  5386. * @return string
  5387. */
  5388. function web_MultigenListClients() {
  5389. $result = '';
  5390. $mlgClientsDb = new NyanORM(MultiGen::CLIENTS);
  5391. $allClients = $mlgClientsDb->getAll();
  5392. $mlgEcn = new MultigenECN();
  5393. if (!empty($allClients)) {
  5394. $cells = wf_TableCell(__('IP'));
  5395. $cells .= wf_TableCell(__('NAS name'));
  5396. $cells .= wf_TableCell(__('RADIUS secret'));
  5397. $rows = wf_TableRow($cells, 'row1');
  5398. foreach ($allClients as $io => $each) {
  5399. $cells = wf_TableCell($each['nasname']);
  5400. $cells .= wf_TableCell($each['shortname'] . $mlgEcn->getIndicator($each['nasname']));
  5401. $cells .= wf_TableCell($each['secret']);
  5402. $rows .= wf_TableRow($cells, 'row5');
  5403. }
  5404. $result .= wf_TableBody($rows, '100%', '0', 'sortable');
  5405. } else {
  5406. $messages = new UbillingMessageHelper();
  5407. $result .= $messages->getStyledMessage(__('Nothing found'), 'warning');
  5408. }
  5409. $result .= wf_delimiter();
  5410. $result .= wf_Link(MultigenECN::URL_ME, wf_img('skins/icon_servers.png') . ' ' . __('Custom NAS configuration'), false, 'ubButton');
  5411. return ($result);
  5412. }
  5413. /**
  5414. * Renders current system load average stats
  5415. *
  5416. * @return string
  5417. */
  5418. function web_ReportSysloadRenderLA() {
  5419. $hwInfo = new SystemHwInfo();
  5420. $cpuName = $hwInfo->getCpuName();
  5421. $cpuCoresCount = $hwInfo->getCpuCores();
  5422. $memTotal = $hwInfo->getMemTotal();
  5423. $memTotalLabel = zb_convertSize($memTotal) . ' ' . __('RAM');
  5424. $cpuLabel = __('CPU') . ': ' . $cpuName;
  5425. $coreLabel = $cpuCoresCount . ' ' . __('Cores');
  5426. $osLabel = $hwInfo->getOs() . ' ' . $hwInfo->getOsRelease() . ', ';
  5427. $phpLabel = __('PHP') . ': ' . $hwInfo->getPhpVersion();
  5428. $result = '';
  5429. $result .= wf_tag('h3') . __('System load');
  5430. $result .= ' (' . $cpuLabel . ', ' . $coreLabel . ', ' . $memTotalLabel . '. ' . $osLabel . $phpLabel . ')';
  5431. $result .= wf_tag('h3', true);
  5432. $gL = 40;
  5433. $yL = 70;
  5434. $percOpts = ' max: 100,
  5435. min: 0,
  5436. width: ' . 280 . ', height: ' . 280 . ',
  5437. greenFrom: 0, greenTo: ' . $gL . ',
  5438. yellowFrom:' . $gL . ', yellowTo: ' . $yL . ',
  5439. redFrom: ' . $yL . ', redTo: 100,
  5440. minorTicks: 5
  5441. ';
  5442. $result .= wf_renderGauge($hwInfo->getLoadAvgPercent(), __('on average'), '%', $percOpts, 300);
  5443. $result .= wf_renderGauge($hwInfo->getloadPercent1(), '1' . ' ' . __('minutes'), '%', $percOpts, 300);
  5444. $result .= wf_renderGauge($hwInfo->getLoadPercent5(), '5' . ' ' . __('minutes'), '%', $percOpts, 300);
  5445. $result .= wf_renderGauge($hwInfo->getLoadPercent15(), '15' . ' ' . __('minutes'), '%', $percOpts, 300);
  5446. $result .= wf_CleanDiv();
  5447. $gL = $cpuCoresCount / 4;
  5448. $yL = $cpuCoresCount / 2;
  5449. $laOpts = 'max: ' . $cpuCoresCount . ',
  5450. min: 0,
  5451. width: ' . 280 . ', height: ' . 280 . ',
  5452. greenFrom: 0, greenTo: ' . $gL . ',
  5453. yellowFrom:' . $gL . ', yellowTo: ' . $yL . ',
  5454. redFrom: ' . $yL . ', redTo: ' . $cpuCoresCount . ',
  5455. minorTicks: 5
  5456. ';
  5457. $result .= wf_tag('h3') . __('Load Average') . wf_tag('h3', true);
  5458. $result .= wf_renderGauge($hwInfo->getLa1(), '1' . ' ' . __('minutes'), 'LA', $laOpts, 300);
  5459. $result .= wf_renderGauge($hwInfo->getLa5(), '5' . ' ' . __('minutes'), 'LA', $laOpts, 300);
  5460. $result .= wf_renderGauge($hwInfo->getLa15(), '15' . ' ' . __('minutes'), 'LA', $laOpts, 300);
  5461. $result .= wf_CleanDiv();
  5462. return ($result);
  5463. }
  5464. /**
  5465. * Renders some free space data about free disk space
  5466. *
  5467. * @return string
  5468. */
  5469. function web_ReportSysloadRenderDisksCapacity() {
  5470. global $ubillingConfig;
  5471. $altCfg = $ubillingConfig->getAlter();
  5472. $usedSpaceArr = array();
  5473. $mountPoints = array('/');
  5474. if (@$altCfg['SYSLOAD_DISKS']) {
  5475. $mountPoints = explode(',', $altCfg['SYSLOAD_DISKS']);
  5476. }
  5477. $hwInfo = new SystemHwInfo();
  5478. $hwInfo->setMountPoints($mountPoints);
  5479. $usedSpaceArr = $hwInfo->getAllDiskStats();
  5480. $result = '';
  5481. $result .= wf_tag('h3') . __('Disks capacity') . wf_tag('h3', true);
  5482. $opts = '
  5483. max: 100,
  5484. min: 0,
  5485. width: ' . 280 . ', height: ' . 280 . ',
  5486. greenFrom: 0, greenTo: 70,
  5487. yellowFrom:70, yellowTo: 90,
  5488. redFrom: 90, redTo: 100,
  5489. minorTicks: 5
  5490. ';
  5491. if (!empty($usedSpaceArr)) {
  5492. foreach ($usedSpaceArr as $mountPoint => $spaceStats) {
  5493. $total = zb_convertSize($spaceStats['total']);
  5494. $free = zb_convertSize($spaceStats['free']);
  5495. $partitionLabel = $mountPoint . ' - ' . $free . ' ' . __('of') . ' ' . $total . ' ' . __('Free');
  5496. $result .= wf_renderGauge(round($spaceStats['usedpercent']), $partitionLabel, '%', $opts, 300);
  5497. }
  5498. }
  5499. $result .= wf_CleanDiv();
  5500. return ($result);
  5501. }
  5502. /**
  5503. * Renders current system process list
  5504. *
  5505. * @global object $ubillingConfig
  5506. *
  5507. * @return string
  5508. */
  5509. function web_ReportSysloadRenderTop() {
  5510. global $ubillingConfig;
  5511. $billCfg = $ubillingConfig->getBilling();
  5512. $result = '';
  5513. if (!empty($billCfg['TOP'])) {
  5514. $result .= wf_tag('pre') . shell_exec($billCfg['TOP']) . wf_tag('pre', true);
  5515. } else {
  5516. $messages = new UbillingMessageHelper();
  5517. $result .= $messages->getStyledMessage(__('batch top path') . ' ' . __('is empty'), 'error');
  5518. }
  5519. return ($result);
  5520. }
  5521. /**
  5522. * Renders current system process list
  5523. *
  5524. * @global object $ubillingConfig
  5525. *
  5526. * @return string
  5527. */
  5528. function web_ReportSysloadRenderUptime() {
  5529. $result = '';
  5530. $messages = new UbillingMessageHelper();
  5531. $hwInfo = new SystemHwInfo();
  5532. $uptime = $hwInfo->getUptime();
  5533. $result .= $messages->getStyledMessage(__('Uptime') . ': ' . zb_formatTime($uptime), 'info');
  5534. return ($result);
  5535. }
  5536. /**
  5537. * Renders current system process list
  5538. *
  5539. *
  5540. * @return string
  5541. */
  5542. function web_ReportSysloadRenderDF() {
  5543. $result = '';
  5544. $result .= wf_tag('pre') . shell_exec('df -h') . wf_tag('pre', true);
  5545. return ($result);
  5546. }
  5547. /**
  5548. * Returns simple new administrator registration form
  5549. *
  5550. * @return string
  5551. */
  5552. function web_AdministratorRegForm() {
  5553. $result = '';
  5554. $inputs = '';
  5555. $inputs .= wf_img_sized('skins/admreganim.gif', '', '', '', 'display:block; float:right;');
  5556. $inputs .= wf_HiddenInput('registernewadministrator', 'true');
  5557. $inputs .= wf_TextInput('newadmusername', __('Username'), '', true, 20, 'alphanumeric') . wf_delimiter(0);
  5558. $inputs .= wf_PasswordInput('newadmpass', __('Password'), '', true, 20) . wf_delimiter(0);
  5559. $inputs .= wf_PasswordInput('newadmconf', __('Confirm password'), '', true, 20) . wf_delimiter(0);
  5560. $inputs .= wf_TextInput('email', __('Email'), '', true, 20, 'email') . wf_delimiter(1);
  5561. $inputs .= wf_HiddenInput('userdata[hideemail]', '1');
  5562. $inputs .= wf_HiddenInput('userdata[tz]', '2');
  5563. $inputs .= wf_Submit(__('Administrators registration'));
  5564. $result .= wf_Form('', 'POST', $inputs, 'floatpanels', '', '', '', 'autocomplete="off"');
  5565. return ($result);
  5566. }
  5567. /**
  5568. * Returns simple existing administrator editing form
  5569. *
  5570. * @param string $adminLogin
  5571. *
  5572. * @return string
  5573. */
  5574. function web_AdministratorEditForm($adminLogin) {
  5575. $result = '';
  5576. $userdata = load_user_info($adminLogin);
  5577. if (!empty($userdata)) {
  5578. $inputs = '';
  5579. $avatarImage = gravatar_ShowAdminAvatar($adminLogin, 128);
  5580. $inputs .= wf_tag('div', false, '', 'style="display:block; float:right;"') . $avatarImage . wf_tag('div', true);
  5581. $inputs .= wf_HiddenInput('save', '1');
  5582. $inputs .= wf_HiddenInput('edadmusername', $userdata['username']);
  5583. $passLabel = wf_tag('small') . __('if you do not want change password you must leave this field empty') . wf_tag('small', true);
  5584. $inputs .= wf_PasswordInput('edadmpass', __('New password'), '', true, 20);
  5585. $inputs .= $passLabel . wf_delimiter(0);
  5586. $inputs .= wf_PasswordInput('edadmconf', __('Confirm password'), '', true, 20) . wf_delimiter(0);
  5587. $inputs .= wf_TextInput('email', __('Email'), $userdata['email'], true, 20, 'email') . wf_delimiter(1);
  5588. $inputs .= wf_HiddenInput('userdata[hideemail]', '1');
  5589. $inputs .= wf_HiddenInput('userdata[tz]', '2');
  5590. $inputs .= wf_Submit(__('Save'));
  5591. $result .= wf_Form('', 'POST', $inputs, 'floatpanels', '', '', '', 'autocomplete="off"');
  5592. } else {
  5593. $messages = new UbillingMessageHelper();
  5594. $result .= $messages->getStyledMessage(__('User') . ' ' . $adminLogin, 256 . ' ' . __('Not exists'), 'error');
  5595. }
  5596. return ($result);
  5597. }
  5598. /**
  5599. * Returns bank statements file upload form.
  5600. * Backported from old banksta API as HotFix.
  5601. *
  5602. * @param string $action
  5603. * @param string $method
  5604. * @param string $inputs
  5605. * @param string $class
  5606. *
  5607. * @return string
  5608. */
  5609. function bs_UploadFormBody($action, $method, $inputs, $class = '') {
  5610. $form = wf_Form($action, $method, $inputs, $class, '', '', '', 'enctype="multipart/form-data"');
  5611. return ($form);
  5612. }
  5613. /**
  5614. * Renders list with some controls of available editable config presets
  5615. *
  5616. * @param array $editableConfigs
  5617. *
  5618. * @return string
  5619. */
  5620. function web_RenderEditableConfigPresetsForm($editableConfigs) {
  5621. $result = '';
  5622. $messages = new UbillingMessageHelper();
  5623. if (!empty($editableConfigs)) {
  5624. $cells = wf_TableCell(__('Path'));
  5625. $cells .= wf_TableCell(__('Name'));
  5626. $cells .= wf_TableCell(__('Actions'));
  5627. $rows = wf_TableRow($cells, 'row1');
  5628. foreach ($editableConfigs as $eachPath => $eachName) {
  5629. $cells = wf_TableCell($eachPath);
  5630. $cells .= wf_TableCell($eachName);
  5631. $actLinks = wf_JSAlert('?module=sysconf&delconfpath=' . base64_encode($eachPath), web_delete_icon(), $messages->getDeleteAlert());
  5632. $cells .= wf_TableCell($actLinks);
  5633. $rows .= wf_TableRow($cells, 'row3');
  5634. }
  5635. $result .= wf_TableBody($rows, '100%', 0, '');
  5636. }
  5637. $inputs = wf_TextInput('newconfpath', __('Path'), '', false, 10) . ' ';
  5638. $inputs .= wf_TextInput('newconfname', __('Name'), '', false, 10) . ' ';
  5639. $inputs .= wf_Submit(__('Create'));
  5640. $result .= wf_Form('', 'POST', $inputs, 'glamour');
  5641. return ($result);
  5642. }
  5643. /**
  5644. * Returns X last lines from some text file
  5645. *
  5646. * @global object $ubillingConfig
  5647. * @param string $filePath
  5648. * @param int $linesCount
  5649. *
  5650. * @return string
  5651. */
  5652. function zb_ReadLastLines($filePath, $linesCount) {
  5653. global $ubillingConfig;
  5654. $result = '';
  5655. if (file_exists($filePath)) {
  5656. $billCfg = $ubillingConfig->getBilling();
  5657. $tailPath = $billCfg['TAIL'];
  5658. $command = $tailPath . ' -n ' . $linesCount . ' ' . $filePath;
  5659. $result = shell_exec($command);
  5660. }
  5661. return ($result);
  5662. }
  5663. /**
  5664. * Calculates something? Some hash? Ask what it was https://github.com/S0liter ;)
  5665. *
  5666. * @param int $numbers Some INN?
  5667. *
  5668. * @return string
  5669. */
  5670. function zb_OschadCSgen($numbers) {
  5671. $result = 0;
  5672. if (!empty($numbers)) {
  5673. if (strlen((string) $numbers) >= 10) {
  5674. $result = $numbers[0] * 10 + $numbers[1] * 11 + $numbers[2] * 12 + $numbers[3] * 13 + $numbers[4] * 14 + $numbers[5] * 15 + $numbers[6] * 16 + $numbers[7] * 17 + $numbers[8] * 18 + $numbers[9] * 19;
  5675. }
  5676. }
  5677. return ($result);
  5678. }
  5679. /**
  5680. * Check is some control allowed to output with current administrator rights
  5681. *
  5682. * @param string $right
  5683. * @param string $controlString
  5684. *
  5685. * @return string
  5686. */
  5687. function zb_rightControl($right, $controlString) {
  5688. $result = '';
  5689. if (!empty($right)) {
  5690. if (cfr($right)) {
  5691. $result .= $controlString;
  5692. }
  5693. } else {
  5694. //no specific right required to output control
  5695. $result .= $controlString;
  5696. }
  5697. return ($result);
  5698. }
  5699. /**
  5700. * Replaces some sensitive characters with safer analogs
  5701. *
  5702. * @param string $data
  5703. * @param bool $mres
  5704. *
  5705. * @return string
  5706. */
  5707. function ub_SanitizeData($data, $mres = true) {
  5708. $result = '';
  5709. if ($mres) {
  5710. $result = ubRouting::filters($data, 'mres');
  5711. } else {
  5712. $result = $data;
  5713. }
  5714. $result = str_replace('"', '``', $result);
  5715. $result = str_replace("'", '`', $result);
  5716. return ($result);
  5717. }
  5718. /**
  5719. * Returns data that contained between two string tags
  5720. *
  5721. * @param string $openTag - open tag string. Examples: "(", "[", "{", "[sometag]"
  5722. * @param string $closeTag - close tag string. Examples: ")", "]", "}", "[/sometag]"
  5723. * @param string $stringToParse - just string that contains some data to parse
  5724. * @param bool $mutipleResults - extract just first result as string or all matches as array like match=>match
  5725. *
  5726. * @return string/array
  5727. */
  5728. function zb_ParseTagData($openTag, $closeTag, $stringToParse = '', $mutipleResults = false) {
  5729. $result = '';
  5730. if (!empty($openTag) and !empty($closeTag) and !empty($stringToParse)) {
  5731. $replacements = array(
  5732. '(' => '\(',
  5733. ')' => '\)',
  5734. '[' => '\[',
  5735. ']' => '\]',
  5736. );
  5737. foreach ($replacements as $eachReplaceTag => $eachReplace) {
  5738. $openTag = str_replace($eachReplaceTag, $eachReplace, $openTag);
  5739. $closeTag = str_replace($eachReplaceTag, $eachReplace, $closeTag);
  5740. }
  5741. $pattern = '!' . $openTag . '(.*?)' . $closeTag . '!si';
  5742. if ($mutipleResults) {
  5743. $result = array();
  5744. if (preg_match_all($pattern, $stringToParse, $matches)) {
  5745. if (isset($matches[1])) {
  5746. if (!empty($matches[1])) {
  5747. foreach ($matches[1] as $io => $each) {
  5748. $result[$each] = $each;
  5749. }
  5750. }
  5751. }
  5752. }
  5753. } else {
  5754. if (preg_match($pattern, $stringToParse, $matches)) {
  5755. if (isset($matches[1])) {
  5756. $result = $matches[1];
  5757. }
  5758. }
  5759. }
  5760. }
  5761. return ($result);
  5762. }
  5763. /**
  5764. * Predicts the next value using simple exponential smoothing with a trend using Holt-Winters method.
  5765. *
  5766. * @param array $data
  5767. *
  5768. * @return float
  5769. */
  5770. function zb_forecastHoltWinters($data) {
  5771. $alpha = 0.2;
  5772. $beta = 0.1;
  5773. $forecast_length = 1;
  5774. $data_length = count($data);
  5775. $level = $data[0];
  5776. $trend = ($data[1] - $data[0]) / 2;
  5777. for ($i = 2; $i < $data_length; $i++) {
  5778. $last_level = $level;
  5779. $last_trend = $trend;
  5780. $level = $alpha * $data[$i] + (1 - $alpha) * ($last_level + $last_trend);
  5781. $trend = $beta * ($level - $last_level) + (1 - $beta) * $last_trend;
  5782. }
  5783. $last_level = $level;
  5784. $last_trend = $trend;
  5785. for ($i = 0; $i < $forecast_length; $i++) {
  5786. $forecast = $last_level + $last_trend * ($i + 1);
  5787. }
  5788. return ($forecast);
  5789. }
  5790. /**
  5791. * Checks is request using secure https connection or not
  5792. *
  5793. * @return bool
  5794. */
  5795. function zb_isHttpsRequest() {
  5796. $result = false;
  5797. if (isset($_SERVER['REQUEST_SCHEME'])) {
  5798. if ($_SERVER['REQUEST_SCHEME'] == 'https') {
  5799. $result = true;
  5800. }
  5801. }
  5802. return ($result);
  5803. }
  5804. /**
  5805. * Returns GPS location button for filling specified input with geo data
  5806. *
  5807. * @param string $inputId
  5808. *
  5809. * @return string
  5810. */
  5811. function web_GPSLocationFillInputControl($inputId) {
  5812. $result = '';
  5813. $result .= wf_tag('script');
  5814. $result .= '
  5815. function getGeoPosition() {
  5816. if(navigator.geolocation) {
  5817. document.getElementById("gpswaitcontainer").innerHTML = " <img src=skins/ui-anim_basic_16x16.gif width=12> ";
  5818. navigator.geolocation.getCurrentPosition(function(position) {
  5819. var positionData = position.coords.latitude + "," + position.coords.longitude;
  5820. document.getElementById("' . $inputId . '").value = positionData;
  5821. document.getElementById("gpswaitcontainer").innerHTML = "";
  5822. });
  5823. } else {
  5824. alert("' . __('Sorry, your browser does not support HTML5 geolocation') . '");
  5825. }
  5826. }';
  5827. $result .= wf_tag('script', true);
  5828. $result .= wf_tag('div', false, '', 'id="gpswaitcontainer" style="float:left;"') . wf_tag('div', true);
  5829. $result .= wf_tag('button', false, '', 'type="button" onclick="getGeoPosition();"') . 'GPS ' . __('Location') . wf_tag('button', true);
  5830. return ($result);
  5831. }
  5832. /**
  5833. * Returns cutted unicode string if its required
  5834. *
  5835. * @param string $string
  5836. * @param int $size
  5837. *
  5838. * @return string
  5839. */
  5840. function zb_cutString($string, $size) {
  5841. if ((mb_strlen($string, 'UTF-8') > $size)) {
  5842. $string = mb_substr($string, 0, $size, 'utf-8') . '...';
  5843. }
  5844. return ($string);
  5845. }
  5846. /**
  5847. * Converts a $delimited_string, delimited with $delimiter, like 'abc, defg, abracadabra' or '1, 4,5, 11,'
  5848. * into a one-dimensional array, like [abc, defg, abracadabra] or [1, 4, 5, 11]
  5849. * or a two-dimensional associative array, like [abc => abc, defg => defg, abracadabra => abracadabra]
  5850. * or [1 => 1, 4 => 4, 5 => 5, 11 => 11]
  5851. * with or without any DUPLICATES
  5852. *
  5853. * It supposed that one using this function understands that $assocValuesAsKeys and $allowDuplicates
  5854. * are two SELF-EXCLUSIONAL parameters
  5855. *
  5856. * @param $delimited_string
  5857. * @param $delimiter
  5858. * @param $assocValuesAsKeys
  5859. * @param $allowDuplicates
  5860. *
  5861. * @return array
  5862. */
  5863. function zb_DelimitedStringToArray($delimited_string, $delimiter = ',', $assocValuesAsKeys = false, $allowDuplicates = false) {
  5864. $result = array();
  5865. //$allowDuplicates = ($assocValuesAsKeys) ? false : $allowDuplicates;
  5866. if (!empty($delimited_string)) {
  5867. $tmp_arr = explode($delimiter, trim($delimited_string, $delimiter . ' '));
  5868. foreach ($tmp_arr as $eachElem) {
  5869. if (!$allowDuplicates and in_array(trim($eachElem), array_values($result))) {
  5870. continue;
  5871. }
  5872. if ($assocValuesAsKeys) {
  5873. $result[trim($eachElem)] = trim($eachElem);
  5874. } else {
  5875. $result[] = trim($eachElem);
  5876. }
  5877. }
  5878. }
  5879. return ($result);
  5880. }
  5881. /**
  5882. * Intended to create string suitable for an SQL WHERE IN clause usage from a $delimited_string, delimited with $delimiter
  5883. *
  5884. * @param $delimited_string
  5885. * @param $delimiter
  5886. * @param $stringINClause
  5887. *
  5888. * @return string
  5889. */
  5890. function zb_DelimitedStringToSQLWHEREIN($delimited_string, $delimiter = ',', $stringINClause = false) {
  5891. $whereStr = '';
  5892. $valuesArr = zb_DelimitedStringToArray($delimited_string, $delimiter);
  5893. if (!empty($valuesArr)) {
  5894. foreach ($valuesArr as $eachElem) {
  5895. if (!empty($eachElem)) {
  5896. $whereStr .= ($stringINClause) ? " '" . $eachElem . "', " : " " . $eachElem . ", ";
  5897. }
  5898. }
  5899. $whereStr = trim($whereStr, ', ');
  5900. }
  5901. return ($whereStr);
  5902. }
  5903. /**
  5904. * Intended to create string suitable for an SQL WHERE IN clause usage from an one-dimensional array of values
  5905. *
  5906. * @param $valuesArr
  5907. * @param $stringINClause
  5908. *
  5909. * @return string
  5910. */
  5911. function zb_ArrayToSQLWHEREIN($valuesArr, $stringINClause = false) {
  5912. $whereStr = '';
  5913. if (!empty($valuesArr)) {
  5914. foreach ($valuesArr as $eachElem) {
  5915. if (!empty($eachElem)) {
  5916. $whereStr .= ($stringINClause) ? " '" . $eachElem . "', " : " " . $eachElem . ", ";
  5917. }
  5918. }
  5919. $whereStr = trim($whereStr, ', ');
  5920. }
  5921. return ($whereStr);
  5922. }
  5923. /**
  5924. * Returns game icon and link as standard panel
  5925. *
  5926. * @return string
  5927. */
  5928. function zb_buildGameIcon($link, $icon, $text) {
  5929. $icon_path = '';
  5930. if (!ispos($icon, 'http')) {
  5931. $icon_path = 'modules/jsc/procrastdata/icons/'; //local icon?
  5932. }
  5933. $task_link = $link;
  5934. $task_icon = $icon_path . $icon;
  5935. $task_text = $text;
  5936. $tbiconsize = '128';
  5937. $template = wf_tag('div', false, 'dashtask', 'style="height:' . ($tbiconsize + 30) . 'px; width:' . ($tbiconsize + 30) . 'px;"');
  5938. $template .= wf_tag('a', false, '', 'href="' . $task_link . '"');
  5939. $template .= wf_tag('img', false, '', 'src="' . $task_icon . '" border="0" width="' . $tbiconsize . '" height="' . $tbiconsize . '" alt="' . $task_text . '" title="' . $task_text . '"');
  5940. $template .= wf_tag('a', true);
  5941. $template .= wf_tag('br');
  5942. $template .= wf_tag('br');
  5943. $template .= $task_text;
  5944. $template .= wf_tag('div', true);
  5945. return ($template);
  5946. }
  5947. /**
  5948. * Generates a random name based on the current language.
  5949. *
  5950. * @return string The generated random name.
  5951. */
  5952. function zb_GenerateRandomName() {
  5953. $curLang = curlang();
  5954. $result = '';
  5955. switch ($curLang) {
  5956. case 'uk':
  5957. $surnames = array("Мельник", "Шевченко", "Коваленко", "Бондаренко", "Бойко", "Ткаченко", "Кравченко", "Ковальчук", "Коваль", "Олійник", "Шевчук", "Поліщук", "Іванова", "Ткачук", "Савченко", "Бондар", "Марченко", "Руденко", "Мороз", "Лисенко", "Петренко", "Клименко", "Павленко", "Кравчук", "Іванов", "Кузьменко", "Пономаренко", "Савчук", "Василенко", "Левченко", "Харченко", "Сидоренко", "Карпенко", "Гаврилюк", "Швець", "Мельничук", "Попова", "Романюк", "Панченко", "Юрченко", "Мазур", "Хоменко", "Попович", "Павлюк", "Кушнір", "Литвиненко", "Мартинюк", "Гончаренко", "Приходько", "Костенко", "Кулик", "Романенко", "Костюк", "Семенюк", "Назаренко", "Ткач", "Кравець", "Коломієць", "Козак", "Яковенко", "Федоренко", "Ковтун", "Білоус", "Нестеренко", "Терещенко", "Колесник", "Попов", "Зінченко", "Тарасенко", "Міщенко", "Вовк", "Демченко", "Дяченко", "Ковальова", "Пилипенко", "Іщенко", "Макаренко", "Бабенко", "Кириченко", "Тищенко", "Тимошенко", "Жук", "Москаленко", "Крюгер", "Вурхіз", "Хьюіт", "Маєрс", "Марчук", "Власенко", "Гуменюк", "Яценко", "Радченко", "Герасименко", "Сергієнко", "Корнієнко", "Гончар", "Мартиненко", "Гордієнко", "Степаненко", "Прокопенко", "Шульга", "Волошин", "Величко", "Денисенко");
  5958. $names = array("Ніка", "Адріана", "Адріан", "Тіна", "Аліна", "Ангеліна", "Алінка", "Ліна", "Аліса", "Алла", "Альберт", "Альбіна", "Альбінка", "Альфред", "Анастасія", "Настя", "Настася", "Настечка", "Настуня", "Настуся", "Ната", "Стася", "Анатолій", "Толя", "Анжела", "Анжеліка", "Анна", "Ганна", "Аня", "Аннуся", "Анюта", "Нюта", "Антін", "Антон", "Тоня", "Антоніна", "Тося", "Ніна", "Анфіса", "Поліна", "Аркадія", "Аркадій", "Арсен", "Арсеній", "Арсенія", "Сеня", "Артемій", "Аурика", "Афанасія", "Афанасій", "Барбара", "Богдана", "Богдан", "Богданка", "Даня", "Богуслава", "Богуслав", "Богуся", "Слава", "Божена", "Борислав", "Броніслава", "Броніслав", "Валентина", "Валентин", "Валерія", "Валерій", "Варвара", "Варонька", "Василина", "Василь", "Вася", "Вероніка", "Віра", "Віка", "Віта", "Вікторія", "Лена", "Іна", "Інна", "Оля", "Віолетта", "Віолета", "Вірослава", "Вірослав", "Віталій", "Віталія", "Влада", "Владислава", "Влад", "Лада", "Владилена", "Владилен", "Влада", "Лада", "Владислав", "Владлина", "Владлин", "Владлен", "Владлєн", "Володимир", "Володя", "В'ячеслава", "В'ячеслав", "Вячеслава", "Вячеслав", "Галина", "Галя", "Галка", "Олена", "Георгій", "Іна", "Гертруда", "Горислава", "Дарина", "Даша", "Дарія", "Даринка", "Дарка", "Діана", "Діна", "Елеонора", "Єлизавета", "Ерік", "Євгенія", "Євген", "Женя", "Дуня", "Єкатерина", "Катерина", "Ліза", "Жанна", "Іванна", "Зіна", "Зоряна", "Зоря", "Іван", "Іванка", "Ігор", "Ілона", "Інга", "Інна", "Ірина", "Іра", "Ірма", "Йосип", "Карина", "Катя", "Кіра", "Лара", "Лєра", "Костя", "Корнелія", "Корнелій", "Ксенія", "Оксана", "Ксеня", "Лариса", "Лев", "Леся", "Олеся", "Олександра", "Лідія", "Лілія", "Ліля", "Любов", "Люба", "Любомира", "Людмила", "Люся", "Люда", "Любослава", "Ляна", "Маргарита", "Маруся", "Марта", "Марія", "Марійка", "Марічка", "Маша", "Марина", "Міла", "Мирослава", "Мирослав", "Міра", "Михайло", "Надія", "Надя", "Наталка", "Наташа", "Саня", "Єлена", "Оленка", "Олівія", "Ольга", "Олег", "Орест", "Павло", "Паша", "Параска", "Регіна", "Римма", "Ярина", "Роза", "Роксана", "Роксолана", "Роман", "Ростислава", "Ростислав", "Руслана", "Руслан", "Лана", "Сара", "Світлана", "Свєта", "Святослав", "Серафима", "Серафим", "Семен", "Сніжана", "Соломія", "Соня", "Софія", "Софійка", "Софа", "Станіслав", "Сюзанна", "Таїсія", "Тася", "Тая", "Тамара", "Тома", "Тетяна", "Таня", "Христина", "Юлія", "Уляна", "Тіна", "Христя", "Юля", "Яна", "Ян", "Ярослава", "Ярослав", "Адам", "Адріян", "Адріан", "Анатолій", "Андрій", "Антон", "Аркадій", "Арсен", "Арсеній", "Артем", "Артур", "Богдан", "Богуслав", "Борис", "Валентин", "Валерій", "Василь", "Вадим", "Вадім", "Вадік", "Вадик", "Віктор", "Віталій", "Влад", "Владислав", "Володимир", "Всеволод", "В'ячеслав", "Вячеслав", "Гаврило", "Геннадій", "Генадій", "Георгій", "Герасим", "Гліб", "Глеб", "Гнат", "Григорій", "Данило", "Денис", "Дмитро", "Євген", "Євгеній", "Зорян", "Іван", "Ігор", "Ілля", "Кирило", "Костянтин", "Лев", "Левко", "Леонід", "Лук'ян", "Лукян", "Любомир", "Маркіян", "Макар", "Максим", "Макс", "Марко", "Матвій", "Микита", "Микола", "Мирон", "Мирослав", "Михайло", "Нестор", "Олег", "Олександр", "Олексій", "Омелян", "Орест", "Остап", "Павло", "Пантелеймон", "Панас", "Петро", "Пилип", "Потап", "Родіон", "Роман", "Ростислав", "Руслан", "Святослав", "Семен", "Сергій", "Слава", "Станислав", "Станіслав", "Степан", "Тарас", "Федір", "Яків", "Ян", "Ярослав");
  5959. break;
  5960. case 'ru':
  5961. $surnames = array("Смирнов", "Иванов", "Кузнецов", "Соколов", "Попов", "Лебедев", "Козлов", "Новиков", "Морозов", "Петров", "Волков", "Соловьёв", "Васильев", "Зайцев", "Павлов", "Семёнов", "Голубев", "Виноградов", "Богданов", "Воробьёв", "Фёдоров", "Михайлов", "Беляев", "Тарасов", "Белов", "Комаров", "Орлов", "Киселёв", "Макаров", "Андреев", "Ковалёв", "Ильин", "Гусев", "Титов", "Кузьмин", "Кудрявцев", "Баранов", "Куликов", "Алексеев", "Степанов", "Яковлев", "Сорокин", "Сергеев", "Романов", "Захаров", "Борисов", "Королёв", "Герасимов", "Пономарёв", "Григорьев", "Лазарев", "Медведев", "Ершов", "Никитин", "Соболев", "Рябов", "Поляков", "Цветков", "Данилов", "Жуков", "Фролов", "Журавлёв", "Николаев", "Крылов", "Максимов", "Сидоров", "Осипов", "Белоусов", "Федотов", "Дорофеев", "Егоров", "Матвеев", "Бобров", "Дмитриев", "Калинин", "Анисимов", "Петухов", "Антонов", "Тимофеев", "Никифоров", "Веселов", "Филиппов", "Марков", "Большаков", "Суханов", "Миронов", "Ширяев", "Александров", "Коновалов", "Шестаков", "Казаков", "Ефимов", "Денисов", "Громов", "Фомин", "Давыдов", "Мельников", "Щербаков", "Блинов", "Колесников", "Карпов", "Афанасьев", "Власов", "Маслов", "Исаков", "Тихонов", "Аксёнов", "Гаврилов", "Родионов", "Котов", "Горбунов", "Кудряшов", "Быков", "Зуев", "Третьяков", "Савельев", "Панов", "Рыбаков", "Суворов", "Абрамов", "Воронов", "Мухин", "Архипов", "Трофимов", "Мартынов", "Емельянов", "Горшков", "Чернов", "Овчинников", "Селезнёв", "Панфилов", "Копылов", "Михеев", "Галкин", "Назаров", "Лобанов", "Лукин", "Беляков", "Потапов", "Некрасов", "Жданов", "Наумов", "Шилов", "Воронцов", "Ермаков", "Дроздов", "Игнатьев", "Савин", "Логинов", "Сафонов", "Капустин", "Кириллов", "Моисеев", "Елисеев", "Кошелев", "Костин", "Горбачёв", "Орехов", "Ефремов", "Исаев", "Евдокимов", "Калашников", "Кабанов", "Носков", "Юдин", "Кулагин", "Лапин", "Прохоров", "Нестеров", "Харитонов", "Агафонов", "Муравьёв", "Ларионов", "Федосеев", "Зимин", "Пахомов", "Шубин", "Игнатов", "Филатов", "Крюков", "Рогов", "Кулаков", "Терентьев", "Молчанов", "Владимиров", "Артемьев", "Гурьев", "Зиновьев", "Гришин", "Кононов", "Дементьев", "Ситников", "Симонов", "Мишин", "Фадеев", "Комиссаров", "Мамонтов", "Носов", "Гуляев", "Шаров", "Устинов", "Вишняков", "Евсеев", "Лаврентьев", "Брагин", "Константинов", "Корнилов", "Авдеев", "Зыков", "Бирюков", "Шарапов", "Никонов", "Щукин", "Дьячков", "Одинцов", "Сазонов", "Якушев", "Красильников", "Гордеев", "Самойлов", "Князев", "Беспалов", "Уваров", "Шашков", "Бобылёв", "Доронин", "Белозёров", "Рожков", "Самсонов", "Мясников", "Лихачёв", "Буров", "Сысоев", "Фомичёв", "Русаков", "Стрелков", "Гущин", "Тетерин", "Колобов", "Субботин", "Фокин", "Блохин", "Селиверстов", "Пестов", "Кондратьев", "Силин", "Меркушев", "Лыткин", "Туров");
  5962. $names = array("Аарон", "Абрам", "Аваз", "Аввакум", "Август", "Авдей", "Авраам", "Автандил", "Агап", "Агафон", "Аггей", "Адам", "Адис", "Адольф", "Адриан", "Азарий", "Азат", "Айрат", "Акакий", "Аким", "Алан", "Александр", "Алексей", "Али", "Алихан", "Алоиз", "Альберт", "Альфред", "Амадей", "Амадеус", "Амаяк", "Амвросий", "Анатолий", "Анвар", "Ангел", "Андоим", "Андре", "Андрей", "Аникита", "Антон", "Ануфрий", "Аполлинарий", "Арам", "Арий", "Аристарх", "Аркадий", "Арман", "Армен", "Арно", "Арнольд", "Арсений", "Арслан", "Артем", "Артемий", "Артур", "Архип", "Аскольд", "Афанасий", "Ахмет", "Ашот", "Бежен", "Бенедикт", "Берек", "Бернар", "Богдан", "Боголюб", "Болеслав", "Бонифаций", "Борис", "Борислав", "Боян", "Бруно", "Булат", "Вадим", "Валентин", "Валерий", "Вальтер", "Вардан", "Варлаам", "Варфоломей", "Василий", "Вацлав", "Велизар", "Велор", "Венедикт", "Вениамин", "Викентий", "Виктор", "Вилен", "Вилли", "Вильгельм", "Виссарион", "Виталий", "Витаутас", "Витольд", "Владимир", "Владислав", "Владлен", "Влас", "Володар", "Вольдемар", "Всеволод", "Вячеслав", "Гавриил", "Галактион", "Гарри", "Гастон", "Гаяс", "Гевор", "Геворг", "Геннадий", "Генрих", "Георгий", "Геральд", "Герасим", "Герман", "Глеб", "Гордей", "Гордон", "Горислав", "Градимир", "Григорий", "Гурий", "Густав", "Давид", "Дамир", "Даниил", "Данияр", "Демид", "Демьян", "Денис", "Джамал", "Джереми", "Джордан", "Динасий", "Дмитрий", "Добрыня", "Дональд", "Донат", "Донатос", "Дорофей", "Евгений", "Евграф", "Евдоким", "Евсей", "Евстафий", "Егор", "Елизар", "Елисей", "Емельян", "Еремей", "Ермолай", "Ерофей", "Ефим", "Ефимий", "Ефрем", "Жан", "Ждан", "Жорж", "Заур", "Захар", "Зигмунд", "Зиновий", "Ибрагим", "Иван", "Игнат", "Игорь", "Иероним", "Измаил", "Израиль", "Илиан", "Илларион", "Ильхам", "Илья", "Ильяс", "Иннокентий", "Ион", "Ионос", "Иосиф", "Ипполит", "Ираклий", "Иржи", "Исаак", "Исай", "Исидор", "Искандер", "Казимир", "Камиль", "Карен", "Карим", "Карл", "Ким", "Кирилл", "Клавдий", "Клаус", "Клемент", "Клим", "Клод", "Кондрат", "Конкордий", "Конрад", "Константин", "Корней", "Корнилий", "Ксанф", "Кузьма", "Лаврентий", "Лазарь", "Лев", "Леван", "Левон", "Ленар", "Леон", "Леонард", "Леонид", "Леонтий", "Леопольд", "Лука", "Лукьян", "Любим", "Любомир", "Людвиг", "Люсьен", "Мадлен", "Май", "Макар", "Максим", "Максимилиан", "Максуд", "Мансур", "Мануил", "Марат", "Мариан", "Марк", "Марсель", "Мартин", "Матвей", "Махмуд", "Мераб", "Мефодий", "Мечеслав", "Милан", "Мирон", "Мирослав", "Митрофан", "Михаил", "Мичлов", "Модест", "Моисей", "Мстислав", "Мурат", "Муслим", "Назар", "Назарий", "Наиль", "Натан", "Наум", "Нестор", "Никанор", "Никита", "Никифор", "Никодим", "Николай", "Никон", "Нильс", "Нисон", "Нифонт", "Норманн", "Овидий", "Олан", "Олег", "Олесь", "Онисим", "Орест", "Осип", "Оскар", "Остап", "Павел", "Панкрат", "Парамон", "Петр", "Пимен", "Платон", "Порфирий", "Потап", "Прокофий", "Прохор", "Равиль", "Радий", "Раймонд", "Раис", "Рамиз", "Рамиль", "Расим", "Ратибор", "Ратмир", "Рафаил", "Рафик", "Рашид", "Рем", "Ренольд", "Ринат", "Рифат", "Рихард", "Ричард", "Роберт", "Родион", "Ролан", "Роман", "Ростислав", "Рубен", "Рудольф", "Руслан", "Рустам", "Рушан", "Сабир", "Савва", "Савелий", "Самсон", "Самуил", "Святослав", "Севастьян", "Северин", "Семен", "Серафим", "Сергей", "Сократ", "Соломон", "Спартак", "Стакрат", "Станимир", "Станислав", "Степан", "Стивен", "Стоян", "Султан", "Таис", "Талик", "Тамаз", "Тарас", "Тельман", "Теодор", "Терентий", "Тибор", "Тигран", "Тигрий", "Тимофей", "Тимур", "Тит", "Тихон", "Томас", "Трифон", "Трофим", "Ульманас", "Устин", "Фаддей", "Фанис", "Фарид", "Фархад", "Федор", "Федот", "Феликс", "Феодосий", "Фердинанд", "Фидель", "Филимон", "Филипп", "Флорентий", "Фома", "Франц", "Фридрих", "Фуад", "Харитон", "Христиан", "Христос", "Христофор", "Цезарь", "Чеслав", "Чингиз", "Шамиль", "Шерлок", "Эдвард", "Эдгар", "Эдмунд", "Эдуард", "Эльдар", "Эмиль", "Эмин", "Эммануил", "Эраст", "Эрик", "Эрнест", "Юлиан", "Юлий", "Юрий", "Юхим", "Яким", "Яков", "Ян", "Януарий", "Яромир", "Ярослав", "Ясон");
  5963. break;
  5964. default:
  5965. $surnames = array("Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez", "Hernandez", "Lopez", "Gonzalez", "Wilson", "Anderson", "Thomas", "Taylor", "Moore", "Jackson", "Martin", "Lee", "Perez", "Thompson", "White", "Harris", "Sanchez", "Clark", "Ramirez", "Lewis", "Robinson", "Walker", "Young", "Allen", "King", "Wright", "Scott", "Torres", "Nguyen", "Hill", "Flores", "Green", "Adams", "Nelson", "Baker", "Hall", "Rivera", "Campbell", "Mitchell", "Carter", "Roberts", "Gomez", "Phillips", "Evans", "Turner", "Diaz", "Parker", "Cruz", "Edwards", "Collins", "Reyes", "Stewart", "Morris", "Morales", "Murphy", "Cook", "Rogers", "Gutierrez", "Ortiz", "Morgan", "Cooper", "Peterson", "Bailey", "Reed", "Kelly", "Howard", "Ramos", "Kim", "Cox", "Ward", "Richardson", "Watson", "Brooks", "Chavez", "Wood", "James", "Bennett", "Gray", "Mendoza", "Ruiz", "Hughes", "Price", "Alvarez", "Castillo", "Sanders", "Patel", "Myers", "Long", "Ross", "Foster", "Jimenez", "Powell", "Jenkins", "Perry", "Russell", "Sullivan", "Bell", "Coleman", "Butler", "Henderson", "Barnes", "Gonzales", "Fisher", "Vasquez", "Simmons", "Romero", "Jordan", "Patterson", "Alexander", "Hamilton", "Graham", "Reynolds", "Griffin", "Wallace", "Moreno", "West", "Cole", "Hayes", "Bryant", "Herrera", "Gibson", "Ellis", "Tran", "Medina", "Aguilar", "Stevens", "Murray", "Ford", "Castro", "Marshall", "Owens", "Harrison", "Fernandez", "Mcdonald", "Woods", "Washington", "Kennedy", "Wells", "Vargas", "Henry", "Chen", "Freeman", "Webb", "Tucker", "Guzman", "Burns", "Crawford", "Olson", "Simpson", "Porter", "Hunter", "Gordon", "Mendez", "Silva", "Shaw", "Snyder", "Mason", "Dixon", "Munoz", "Hunt", "Hicks", "Holmes", "Palmer", "Wagner", "Black", "Robertson", "Boyd", "Rose", "Stone", "Salazar", "Fox", "Warren", "Mills", "Meyer", "Rice", "Schmidt", "Garza", "Daniels", "Ferguson", "Nichols", "Stephens", "Soto", "Weaver", "Ryan", "Gardner", "Payne", "Grant", "Dunn", "Kelley", "Spencer", "Hawkins", "Arnold", "Pierce", "Vazquez", "Hansen", "Peters", "Santos", "Hart", "Bradley", "Knight", "Elliott", "Cunningham", "Duncan", "Armstrong", "Hudson", "Carroll", "Lane", "Riley", "Andrews", "Alvarado", "Ray", "Delgado", "Berry", "Perkins", "Hoffman", "Johnston", "Matthews", "Pena", "Richards", "Contreras", "Willis", "Carpenter", "Lawrence", "Sandoval", "Guerrero", "George", "Chapman", "Rios", "Estrada", "Ortega", "Watkins", "Greene", "Nunez", "Wheeler", "Valdez", "Harper", "Burke", "Larson", "Santiago", "Maldonado", "Morrison", "Franklin", "Carlson", "Austin", "Dominguez", "Carr", "Lawson", "Jacobs", "Obrien", "Lynch", "Singh", "Vega", "Bishop", "Montgomery", "Oliver", "Jensen", "Harvey", "Williamson", "Gilbert", "Dean", "Sims", "Espinoza", "Howell", "Li", "Wong", "Reid", "Hanson", "Le", "Mccoy", "Garrett", "Burton", "Fuller", "Wang", "Weber", "Welch", "Rojas", "Lucas", "Marquez", "Fields", "Park", "Yang", "Little", "Banks", "Padilla", "Day", "Walsh", "Bowman", "Schultz", "Luna", "Fowler", "Mejia", "Davidson", "Acosta", "Brewer", "May", "Holland", "Juarez", "Newman", "Pearson", "Curtis", "Cortez", "Douglas", "Schneider", "Joseph", "Barrett", "Navarro", "Figueroa", "Keller", "Avila", "Wade", "Molina", "Stanley", "Hopkins", "Campos", "Barnett", "Bates", "Chambers", "Caldwell", "Beck", "Lambert", "Miranda", "Byrd", "Craig", "Ayala", "Lowe", "Frazier", "Powers", "Neal", "Leonard", "Gregory", "Carrillo", "Sutton", "Fleming", "Rhodes", "Shelton", "Schwartz", "Norris", "Jennings", "Watts", "Duran", "Walters", "Cohen", "Mcdaniel", "Moran", "Parks", "Steele", "Vaughn", "Becker", "Holt", "Deleon", "Barker", "Terry", "Hale", "Leon", "Hail", "Benson", "Haynes", "Horton", "Miles", "Lyons", "Pham", "Graves", "Bush", "Thornton", "Wolfe", "Warner", "Cabrera", "Mckinney", "Mann", "Zimmerman", "Dawson", "Lara", "Fletcher", "Page", "Mccarthy", "Love", "Robles", "Cervantes", "Solis", "Erickson", "Reeves", "Chang", "Klein", "Salinas", "Fuentes", "Baldwin", "Daniel", "Simon", "Velasquez", "Hardy", "Higgins", "Aguirre", "Lin", "Cummings", "Chandler", "Sharp", "Barber", "Bowen", "Ochoa", "Dennis", "Robbins", "Liu", "Ramsey", "Francis", "Griffith", "Paul", "Blair", "Oconnor", "Cardenas", "Pacheco", "Cross", "Calderon", "Quinn", "Moss", "Swanson", "Chan", "Rivas", "Khan", "Rodgers", "Serrano", "Fitzgerald", "Rosales", "Stevenson", "Christensen", "Manning", "Gill", "Curry", "Mclaughlin", "Harmon", "Mcgee", "Gross", "Doyle", "Garner", "Newton", "Burgess", "Reese", "Walton", "Blake", "Trujillo", "Adkins", "Brady", "Goodman", "Roman", "Webster", "Goodwin", "Fischer", "Huang", "Potter", "Delacruz", "Montoya", "Todd", "Wu", "Hines", "Mullins", "Castaneda", "Malone", "Cannon", "Tate", "Mack", "Sherman", "Hubbard", "Hodges", "Zhang", "Guerra", "Wolf", "Valencia", "Franco", "Saunders", "Rowe", "Gallagher", "Farmer", "Hammond", "Hampton", "Townsend", "Ingram", "Wise", "Gallegos", "Clarke", "Barton", "Schroeder", "Maxwell", "Waters", "Logan", "Camacho", "Strickland", "Norman", "Person", "Colon", "Parsons", "Frank", "Harrington", "Glover", "Osborne", "Buchanan", "Casey", "Floyd", "Patton", "Ibarra", "Ball", "Tyler", "Suarez", "Bowers", "Orozco", "Salas", "Cobb", "Gibbs", "Andrade", "Bauer", "Conner", "Moody", "Escobar", "Mcguire", "Lloyd", "Mueller", "Hartman", "French", "Kramer", "Mcbride", "Pope", "Lindsey", "Velazquez", "Norton", "Mccormick", "Sparks", "Flynn", "Yates", "Hogan", "Marsh", "Macias", "Villanueva", "Zamora", "Pratt", "Stokes", "Owen", "Ballard", "Lang", "Brock", "Villarreal", "Charles", "Drake", "Barrera", "Cain", "Patrick", "Pineda", "Burnett", "Mercado", "Santana", "Shepherd", "Bautista", "Ali", "Shaffer", "Lamb", "Trevino", "Mckenzie", "Hess", "Beil", "Olsen", "Cochran", "Morton", "Nash", "Wilkins", "Petersen", "Briggs", "Shah", "Roth", "Nicholson", "Holloway", "Lozano", "Flowers", "Rangel", "Hoover", "Arias", "Short", "Mora", "Valenzuela", "Bryan", "Meyers", "Weiss", "Underwood", "Bass", "Greer", "Summers", "Houston", "Carson", "Morrow", "Clayton", "Whitaker", "Decker", "Yoder", "Collier", "Zuniga", "Carey", "Wilcox", "Melendez", "Poole", "Roberson", "Larsen", "Conley", "Davenport", "Copeland", "Massey", "Lam", "Huff", "Rocha", "Cameron", "Jefferson", "Hood", "Monroe", "Anthony", "Pittman", "Huynh", "Randall", "Singleton", "Kirk", "Combs", "Mathis", "Christian", "Skinner", "Bradford", "Richard", "Galvan", "Wall", "Boone", "Kirby", "Wilkinson", "Bridges", "Bruce", "Atkinson", "Velez", "Meza", "Roy", "Vincent", "York", "Hodge", "Villa", "Abbott", "Allison", "Tapia", "Gates", "Chase", "Sosa", "Sweeney", "Farrell", "Wyatt", "Dalton", "Horn", "Barron", "Phelps", "Yu", "Dickerson", "Heath", "Foley", "Atkins", "Mathews", "Bonilla", "Acevedo", "Benitez", "Zavala", "Hensley", "Glenn", "Cisneros", "Harrell", "Shields", "Rubio", "Choi", "Huffman", "Boyer", "Garrison", "Arroyo", "Bond", "Kane", "Hancock", "Callahan", "Dillon", "Cline", "Wiggins", "Grimes", "Arellano", "Melton", "Oneill", "Savage", "Ho", "Beltran", "Pitts", "Parrish", "Ponce", "Rich", "Booth", "Koch", "Golden", "Ware", "Brennan", "Mcdowell", "Marks", "Cantu", "Humphrey", "Baxter", "Sawyer", "Clay", "Tanner", "Hutchinson", "Kaur", "Berg", "Wiley", "Gilmore", "Russo", "Villegas", "Hobbs", "Keith", "Wilkerson", "Ahmed", "Beard", "Mcclain", "Montes", "Mata", "Rosario", "Vang", "S", "S", "Walter", "Henson", "Oneal", "Mosley", "Mcclure", "Beasley", "Stephenson", "Snow", "Huerta", "Preston", "Vance", "Barry", "Johns", "Eaton", "Blackwell", "Dyer", "Prince", "Macdonald", "Solomon", "Guevara", "Stafford", "English", "Hurst", "Woodard", "Cortes", "Shannon", "Kemp", "Nolan", "Mccullough", "Merritt", "Murillo", "Moon", "Salgado", "Strong", "Kline", "Cordova", "Barajas", "Roach", "Rosas", "Winters", "Jacobson", "Lester", "Knox", "Bullock", "Kerr", "Leach", "Meadows", "Davila", "Orr", "Whitehead", "Pruitt", "Kent", "Conway", "Mckee", "Barr", "David", "Dejesus", "Marin", "Berger", "Mcintyre", "Blankenship", "Gaines", "Palacios", "Cuevas", "Bartlett", "Durham", "Dorsey", "Mccall", "Odonnell", "Stein", "Browning", "Stout", "Lowery", "Sloan", "Mclean", "Hendricks", "Calhoun", "Sexton", "Chung", "Gentry", "Hull", "Duarte", "Ellison", "Nielsen", "Gillespie", "Buck", "Middleton", "Sellers", "Leblanc", "Esparza", "Hardin", "Bradshaw", "Mcintosh", "Howe", "Livingston", "Frost", "Glass", "Morse", "Knapp", "Herman", "Stark", "Bravo", "Noble", "Spears", "Weeks", "Corona", "Frederick", "Buckley", "Mcfarland", "Hebert", "Enriquez", "Hickman", "Quintero", "Randolph", "Schaefer", "Walls", "Trejo", "House", "Reilly", "Pennington", "Michael", "Conrad", "Giles", "Benjamin", "Crosby", "Fitzpatrick", "Donovan", "Mays", "Mahoney", "Valentine", "Raymond", "Medrano", "Hahn", "Mcmillan", "Small", "Bentley", "Felix", "Peck", "Lucero", "Boyle", "Hanna", "Pace", "Rush", "Hurley", "Harding", "Mcconnell", "Bernal", "Nava", "Ayers", "Everett", "Ventura", "Avery", "Pugh", "Mayer", "Bender", "Shepard", "Mcmahon", "Landry", "Case", "Sampson", "Moses", "Magana", "Blackburn", "Dunlap", "Gould", "Duffy", "Vaughan", "Herring", "Mckay", "Espinosa", "Rivers", "Farley", "Bernard", "Ashley", "Friedman", "Potts", "Truong", "Costa", "Correa", "Blevins", "Nixon", "Clements", "Fry", "Delarosa", "Best", "Benton", "Lugo", "Portillo", "Dougherty", "Crane", "Haley", "Phan", "Villalobos", "Blanchard", "Horne", "Finley", "Quintana", "Lynn", "Esquivel", "Bean", "Dodson", "Mullen", "Xiong", "Hayden", "Cano", "Levy", "Huber", "Richmond", "Moyer", "Lim", "Frye", "Sheppard", "Mccarty", "Avalos", "Booker", "Waller", "Parra", "Woodward", "Jaramillo", "Krueger", "Rasmussen", "Brandt", "Peralta", "Donaldson", "Stuart", "Faulkner", "Maynard", "Galindo", "Coffey", "Estes", "Sanford", "Burch", "Maddox", "Vo", "Oconnell", "Vu", "Andersen", "Spence", "Mcpherson", "Church", "Schmitt", "Stanton", "Leal", "Cherry", "Compton", "Dudley", "Sierra", "Pollard", "Alfaro", "Hester", "Proctor", "Lu", "Hinton", "Novak", "Good", "Madden", "Mccann", "Terrell", "Jarvis", "Dickson", "Reyna", "Cantrell", "Mayo", "Branch", "Hendrix", "Rollins", "Rowland", "Whitney", "Duke", "Odom", "Daugherty", "Travis", "Tang");
  5966. $names = array("Aaren", "Aarika", "Abagael", "Abagail", "Abbe", "Abbey", "Abbi", "Abbie", "Abby", "Abbye", "Abigael", "Abigail", "Abigale", "Abra", "Ada", "Adah", "Adaline", "Adan", "Adara", "Adda", "Addi", "Addia", "Addie", "Addy", "Adel", "Adela", "Adelaida", "Adelaide", "Adele", "Adelheid", "Adelice", "Adelina", "Adelind", "Adeline", "Adella", "Adelle", "Adena", "Adey", "Adi", "Adiana", "Adina", "Adora", "Adore", "Adoree", "Adorne", "Adrea", "Adria", "Adriaens", "Adrian", "Adriana", "Adriane", "Adrianna", "Adrianne", "Adriena", "Adrienne", "Aeriel", "Aeriela", "Aeriell", "Afton", "Ag", "Agace", "Agata", "Agatha", "Agathe", "Aggi", "Aggie", "Aggy", "Agna", "Agnella", "Agnes", "Agnese", "Agnesse", "Agneta", "Agnola", "Agretha", "Aida", "Aidan", "Aigneis", "Aila", "Aile", "Ailee", "Aileen", "Ailene", "Ailey", "Aili", "Ailina", "Ailis", "Ailsun", "Ailyn", "Aime", "Aimee", "Aimil", "Aindrea", "Ainslee", "Ainsley", "Ainslie", "Ajay", "Alaine", "Alameda", "Alana", "Alanah", "Alane", "Alanna", "Alayne", "Alberta", "Albertina", "Albertine", "Albina", "Alecia", "Aleda", "Aleece", "Aleen", "Alejandra", "Alejandrina", "Alena", "Alene", "Alessandra", "Aleta", "Alethea", "Alex", "Alexa", "Alexandra", "Alexandrina", "Alexi", "Alexia", "Alexina", "Alexine", "Alexis", "Alfi", "Alfie", "Alfreda", "Alfy", "Ali", "Alia", "Alica", "Alice", "Alicea", "Alicia", "Alida", "Alidia", "Alie", "Alika", "Alikee", "Alina", "Aline", "Alis", "Alisa", "Alisha", "Alison", "Alissa", "Alisun", "Alix", "Aliza", "Alla", "Alleen", "Allegra", "Allene", "Alli", "Allianora", "Allie", "Allina", "Allis", "Allison", "Allissa", "Allix", "Allsun", "Allx", "Ally", "Allyce", "Allyn", "Allys", "Allyson", "Alma", "Almeda", "Almeria", "Almeta", "Almira", "Almire", "Aloise", "Aloisia", "Aloysia", "Alta", "Althea", "Alvera", "Alverta", "Alvina", "Alvinia", "Alvira", "Alyce", "Alyda", "Alys", "Alysa", "Alyse", "Alysia", "Alyson", "Alyss", "Alyssa", "Amabel", "Amabelle", "Amalea", "Amalee", "Amaleta", "Amalia", "Amalie", "Amalita", "Amalle", "Amanda", "Amandi", "Amandie", "Amandy", "Amara", "Amargo", "Amata", "Amber", "Amberly", "Ambur", "Ame", "Amelia", "Amelie", "Amelina", "Ameline", "Amelita", "Ami", "Amie", "Amii", "Amil", "Amitie", "Amity", "Ammamaria", "Amy", "Amye", "Ana", "Anabal", "Anabel", "Anabella", "Anabelle", "Analiese", "Analise", "Anallese", "Anallise", "Anastasia", "Anastasie", "Anastassia", "Anatola", "Andee", "Andeee", "Anderea", "Andi", "Andie", "Andra", "Andrea", "Andreana", "Andree", "Andrei", "Andria", "Andriana", "Andriette", "Andromache", "Andy", "Anestassia", "Anet", "Anett", "Anetta", "Anette", "Ange", "Angel", "Angela", "Angele", "Angelia", "Angelica", "Angelika", "Angelina", "Angeline", "Angelique", "Angelita", "Angelle", "Angie", "Angil", "Angy", "Ania", "Anica", "Anissa", "Anita", "Anitra", "Anjanette", "Anjela", "Ann", "Ann-Marie", "Anna", "Anna-Diana", "Anna-Diane", "Anna-Maria", "Annabal", "Annabel", "Annabela", "Annabell", "Annabella", "Annabelle", "Annadiana", "Annadiane", "Annalee", "Annaliese", "Annalise", "Annamaria", "Annamarie", "Anne", "Anne-Corinne", "Anne-Marie", "Annecorinne", "Anneliese", "Annelise", "Annemarie", "Annetta", "Annette", "Anni", "Annice", "Annie", "Annis", "Annissa", "Annmaria", "Annmarie", "Annnora", "Annora", "Anny", "Anselma", "Ansley", "Anstice", "Anthe", "Anthea", "Anthia", "Anthiathia", "Antoinette", "Antonella", "Antonetta", "Antonia", "Antonie", "Antonietta", "Antonina", "Anya", "Appolonia", "April", "Aprilette", "Ara", "Arabel", "Arabela", "Arabele", "Arabella", "Arabelle", "Arda", "Ardath", "Ardeen", "Ardelia", "Ardelis", "Ardella", "Ardelle", "Arden", "Ardene", "Ardenia", "Ardine", "Ardis", "Ardisj", "Ardith", "Ardra", "Ardyce", "Ardys", "Ardyth", "Aretha", "Ariadne", "Ariana", "Aridatha", "Ariel", "Ariela", "Ariella", "Arielle", "Arlana", "Arlee", "Arleen", "Arlen", "Arlena", "Arlene", "Arleta", "Arlette", "Arleyne", "Arlie", "Arliene", "Arlina", "Arlinda", "Arline", "Arluene", "Arly", "Arlyn", "Arlyne", "Aryn", "Ashely", "Ashia", "Ashien", "Ashil", "Ashla", "Ashlan", "Ashlee", "Ashleigh", "Ashlen", "Ashley", "Ashli", "Ashlie", "Ashly", "Asia", "Astra", "Astrid", "Astrix", "Atalanta", "Athena", "Athene", "Atlanta", "Atlante", "Auberta", "Aubine", "Aubree", "Aubrette", "Aubrey", "Aubrie", "Aubry", "Audi", "Audie", "Audra", "Audre", "Audrey", "Audrie", "Audry", "Audrye", "Audy", "Augusta", "Auguste", "Augustina", "Augustine", "Aundrea", "Aura", "Aurea", "Aurel", "Aurelea", "Aurelia", "Aurelie", "Auria", "Aurie", "Aurilia", "Aurlie", "Auroora", "Aurora", "Aurore", "Austin", "Austina", "Austine", "Ava", "Aveline", "Averil", "Averyl", "Avie", "Avis", "Aviva", "Avivah", "Avril", "Avrit", "Ayn", "Bab", "Babara", "Babb", "Babbette", "Babbie", "Babette", "Babita", "Babs", "Bambi", "Bambie", "Bamby", "Barb", "Barbabra", "Barbara", "Barbara-Anne", "Barbaraanne", "Barbe", "Barbee", "Barbette", "Barbey", "Barbi", "Barbie", "Barbra", "Barby", "Bari", "Barrie", "Barry", "Basia", "Bathsheba", "Batsheva", "Bea", "Beatrice", "Beatrisa", "Beatrix", "Beatriz", "Bebe", "Becca", "Becka", "Becki", "Beckie", "Becky", "Bee", "Beilul", "Beitris", "Bekki", "Bel", "Belia", "Belicia", "Belinda", "Belita", "Bell", "Bella", "Bellanca", "Belle", "Bellina", "Belva", "Belvia", "Bendite", "Benedetta", "Benedicta", "Benedikta", "Benetta", "Benita", "Benni", "Bennie", "Benny", "Benoite", "Berenice", "Beret", "Berget", "Berna", "Bernadene", "Bernadette", "Bernadina", "Bernadine", "Bernardina", "Bernardine", "Bernelle", "Bernete", "Bernetta", "Bernette", "Berni", "Bernice", "Bernie", "Bernita", "Berny", "Berri", "Berrie", "Berry", "Bert", "Berta", "Berte", "Bertha", "Berthe", "Berti", "Bertie", "Bertina", "Bertine", "Berty", "Beryl", "Beryle", "Bess", "Bessie", "Bessy", "Beth", "Bethanne", "Bethany", "Bethena", "Bethina", "Betsey", "Betsy", "Betta", "Bette", "Bette-Ann", "Betteann", "Betteanne", "Betti", "Bettina", "Bettine", "Betty", "Bettye", "Beulah", "Bev", "Beverie", "Beverlee", "Beverley", "Beverlie", "Beverly", "Bevvy", "Bianca", "Bianka", "Bibbie", "Bibby", "Bibbye", "Bibi", "Biddie", "Biddy", "Bidget", "Bili", "Bill", "Billi", "Billie", "Billy", "Billye", "Binni", "Binnie", "Binny", "Bird", "Birdie", "Birgit", "Birgitta", "Blair", "Blaire", "Blake", "Blakelee", "Blakeley", "Blanca", "Blanch", "Blancha", "Blanche", "Blinni", "Blinnie", "Blinny", "Bliss", "Blisse", "Blithe", "Blondell", "Blondelle", "Blondie", "Blondy", "Blythe", "Bobbe", "Bobbee", "Bobbette", "Bobbi", "Bobbie", "Bobby", "Bobbye", "Bobette", "Bobina", "Bobine", "Bobinette", "Bonita", "Bonnee", "Bonni", "Bonnibelle", "Bonnie", "Bonny", "Brana", "Brandais", "Brande", "Brandea", "Brandi", "Brandice", "Brandie", "Brandise", "Brandy", "Breanne", "Brear", "Bree", "Breena", "Bren", "Brena", "Brenda", "Brenn", "Brenna", "Brett", "Bria", "Briana", "Brianna", "Brianne", "Bride", "Bridget", "Bridgette", "Bridie", "Brier", "Brietta", "Brigid", "Brigida", "Brigit", "Brigitta", "Brigitte", "Brina", "Briney", "Brinn", "Brinna", "Briny", "Brit", "Brita", "Britney", "Britni", "Britt", "Britta", "Brittan", "Brittaney", "Brittani", "Brittany", "Britte", "Britteny", "Brittne", "Brittney", "Brittni", "Brook", "Brooke", "Brooks", "Brunhilda", "Brunhilde", "Bryana", "Bryn", "Bryna", "Brynn", "Brynna", "Brynne", "Buffy", "Bunni", "Bunnie", "Bunny", "Cacilia", "Cacilie", "Cahra", "Cairistiona", "Caitlin", "Caitrin", "Cal", "Calida", "Calla", "Calley", "Calli", "Callida", "Callie", "Cally", "Calypso", "Cam", "Camala", "Camel", "Camella", "Camellia", "Cami", "Camila", "Camile", "Camilla", "Camille", "Cammi", "Cammie", "Cammy", "Candace", "Candi", "Candice", "Candida", "Candide", "Candie", "Candis", "Candra", "Candy", "Caprice", "Cara", "Caralie", "Caren", "Carena", "Caresa", "Caressa", "Caresse", "Carey", "Cari", "Caria", "Carie", "Caril", "Carilyn", "Carin", "Carina", "Carine", "Cariotta", "Carissa", "Carita", "Caritta", "Carla", "Carlee", "Carleen", "Carlen", "Carlene", "Carley", "Carlie", "Carlin", "Carlina", "Carline", "Carlita", "Carlota", "Carlotta", "Carly", "Carlye", "Carlyn", "Carlynn", "Carlynne", "Carma", "Carmel", "Carmela", "Carmelia", "Carmelina", "Carmelita", "Carmella", "Carmelle", "Carmen", "Carmencita", "Carmina", "Carmine", "Carmita", "Carmon", "Caro", "Carol", "Carol-Jean", "Carola", "Carolan", "Carolann", "Carole", "Carolee", "Carolin", "Carolina", "Caroline", "Caroljean", "Carolyn", "Carolyne", "Carolynn", "Caron", "Carree", "Carri", "Carrie", "Carrissa", "Carroll", "Carry", "Cary", "Caryl", "Caryn", "Casandra", "Casey", "Casi", "Casie", "Cass", "Cassandra", "Cassandre", "Cassandry", "Cassaundra", "Cassey", "Cassi", "Cassie", "Cassondra", "Cassy", "Catarina", "Cate", "Caterina", "Catha", "Catharina", "Catharine", "Cathe", "Cathee", "Catherin", "Catherina", "Catherine", "Cathi", "Cathie", "Cathleen", "Cathlene", "Cathrin", "Cathrine", "Cathryn", "Cathy", "Cathyleen", "Cati", "Catie", "Catina", "Catlaina", "Catlee", "Catlin", "Catrina", "Catriona", "Caty", "Caye", "Cayla", "Cecelia", "Cecil", "Cecile", "Ceciley", "Cecilia", "Cecilla", "Cecily", "Ceil", "Cele", "Celene", "Celesta", "Celeste", "Celestia", "Celestina", "Celestine", "Celestyn", "Celestyna", "Celia", "Celie", "Celina", "Celinda", "Celine", "Celinka", "Celisse", "Celka", "Celle", "Cesya", "Chad", "Chanda", "Chandal", "Chandra", "Channa", "Chantal", "Chantalle", "Charil", "Charin", "Charis", "Charissa", "Charisse", "Charita", "Charity", "Charla", "Charlean", "Charleen", "Charlena", "Charlene", "Charline", "Charlot", "Charlotta", "Charlotte", "Charmain", "Charmaine", "Charmane", "Charmian", "Charmine", "Charmion", "Charo", "Charyl", "Chastity", "Chelsae", "Chelsea", "Chelsey", "Chelsie", "Chelsy", "Cher", "Chere", "Cherey", "Cheri", "Cherianne", "Cherice", "Cherida", "Cherie", "Cherilyn", "Cherilynn", "Cherin", "Cherise", "Cherish", "Cherlyn", "Cherri", "Cherrita", "Cherry", "Chery", "Cherye", "Cheryl", "Cheslie", "Chiarra", "Chickie", "Chicky", "Chiquia", "Chiquita", "Chlo", "Chloe", "Chloette", "Chloris", "Chris", "Chrissie", "Chrissy", "Christa", "Christabel", "Christabella", "Christal", "Christalle", "Christan", "Christean", "Christel", "Christen", "Christi", "Christian", "Christiana", "Christiane", "Christie", "Christin", "Christina", "Christine", "Christy", "Christye", "Christyna", "Chrysa", "Chrysler", "Chrystal", "Chryste", "Chrystel", "Cicely", "Cicily", "Ciel", "Cilka", "Cinda", "Cindee", "Cindelyn", "Cinderella", "Cindi", "Cindie", "Cindra", "Cindy", "Cinnamon", "Cissiee", "Cissy", "Clair", "Claire", "Clara", "Clarabelle", "Clare", "Claresta", "Clareta", "Claretta", "Clarette", "Clarey", "Clari", "Claribel", "Clarice", "Clarie", "Clarinda", "Clarine", "Clarissa", "Clarisse", "Clarita", "Clary", "Claude", "Claudelle", "Claudetta", "Claudette", "Claudia", "Claudie", "Claudina", "Claudine", "Clea", "Clem", "Clemence", "Clementia", "Clementina", "Clementine", "Clemmie", "Clemmy", "Cleo", "Cleopatra", "Clerissa", "Clio", "Clo", "Cloe", "Cloris", "Clotilda", "Clovis", "Codee", "Codi", "Codie", "Cody", "Coleen", "Colene", "Coletta", "Colette", "Colleen", "Collen", "Collete", "Collette", "Collie", "Colline", "Colly", "Con", "Concettina", "Conchita", "Concordia", "Conni", "Connie", "Conny", "Consolata", "Constance", "Constancia", "Constancy", "Constanta", "Constantia", "Constantina", "Constantine", "Consuela", "Consuelo", "Cookie", "Cora", "Corabel", "Corabella", "Corabelle", "Coral", "Coralie", "Coraline", "Coralyn", "Cordelia", "Cordelie", "Cordey", "Cordi", "Cordie", "Cordula", "Cordy", "Coreen", "Corella", "Corenda", "Corene", "Coretta", "Corette", "Corey", "Cori", "Corie", "Corilla", "Corina", "Corine", "Corinna", "Corinne", "Coriss", "Corissa", "Corliss", "Corly", "Cornela", "Cornelia", "Cornelle", "Cornie", "Corny", "Correna", "Correy", "Corri", "Corrianne", "Corrie", "Corrina", "Corrine", "Corrinne", "Corry", "Cortney", "Cory", "Cosetta", "Cosette", "Costanza", "Courtenay", "Courtnay", "Courtney", "Crin", "Cris", "Crissie", "Crissy", "Crista", "Cristabel", "Cristal", "Cristen", "Cristi", "Cristie", "Cristin", "Cristina", "Cristine", "Cristionna", "Cristy", "Crysta", "Crystal", "Crystie", "Cthrine", "Cyb", "Cybil", "Cybill", "Cymbre", "Cynde", "Cyndi", "Cyndia", "Cyndie", "Cyndy", "Cynthea", "Cynthia", "Cynthie", "Cynthy", "Dacey", "Dacia", "Dacie", "Dacy", "Dael", "Daffi", "Daffie", "Daffy", "Dagmar", "Dahlia", "Daile", "Daisey", "Daisi", "Daisie", "Daisy", "Dale", "Dalenna", "Dalia", "Dalila", "Dallas", "Daloris", "Damara", "Damaris", "Damita", "Dana", "Danell", "Danella", "Danette", "Dani", "Dania", "Danica", "Danice", "Daniela", "Daniele", "Daniella", "Danielle", "Danika", "Danila", "Danit", "Danita", "Danna", "Danni", "Dannie", "Danny", "Dannye", "Danya", "Danyelle", "Danyette", "Daphene", "Daphna", "Daphne", "Dara", "Darb", "Darbie", "Darby", "Darcee", "Darcey", "Darci", "Darcie", "Darcy", "Darda", "Dareen", "Darell", "Darelle", "Dari", "Daria", "Darice", "Darla", "Darleen", "Darlene", "Darline", "Darlleen", "Daron", "Darrelle", "Darryl", "Darsey", "Darsie", "Darya", "Daryl", "Daryn", "Dasha", "Dasi", "Dasie", "Dasya", "Datha", "Daune", "Daveen", "Daveta", "Davida", "Davina", "Davine", "Davita", "Dawn", "Dawna", "Dayle", "Dayna", "Ddene", "De", "Deana", "Deane", "Deanna", "Deanne", "Deb", "Debbi", "Debbie", "Debby", "Debee", "Debera", "Debi", "Debor", "Debora", "Deborah", "Debra", "Dede", "Dedie", "Dedra", "Dee", "Dee Dee", "Deeann", "Deeanne", "Deedee", "Deena", "Deerdre", "Deeyn", "Dehlia", "Deidre", "Deina", "Deirdre", "Del", "Dela", "Delcina", "Delcine", "Delia", "Delila", "Delilah", "Delinda", "Dell", "Della", "Delly", "Delora", "Delores", "Deloria", "Deloris", "Delphine", "Delphinia", "Demeter", "Demetra", "Demetria", "Demetris", "Dena", "Deni", "Denice", "Denise", "Denna", "Denni", "Dennie", "Denny", "Deny", "Denys", "Denyse", "Deonne", "Desdemona", "Desirae", "Desiree", "Desiri", "Deva", "Devan", "Devi", "Devin", "Devina", "Devinne", "Devon", "Devondra", "Devonna", "Devonne", "Devora", "Di", "Diahann", "Dian", "Diana", "Diandra", "Diane", "Diane-Marie", "Dianemarie", "Diann", "Dianna", "Dianne", "Diannne", "Didi", "Dido", "Diena", "Dierdre", "Dina", "Dinah", "Dinnie", "Dinny", "Dion", "Dione", "Dionis", "Dionne", "Dita", "Dix", "Dixie", "Dniren", "Dode", "Dodi", "Dodie", "Dody", "Doe", "Doll", "Dolley", "Dolli", "Dollie", "Dolly", "Dolores", "Dolorita", "Doloritas", "Domeniga", "Dominga", "Domini", "Dominica", "Dominique", "Dona", "Donella", "Donelle", "Donetta", "Donia", "Donica", "Donielle", "Donna", "Donnamarie", "Donni", "Donnie", "Donny", "Dora", "Doralia", "Doralin", "Doralyn", "Doralynn", "Doralynne", "Dore", "Doreen", "Dorelia", "Dorella", "Dorelle", "Dorena", "Dorene", "Doretta", "Dorette", "Dorey", "Dori", "Doria", "Dorian", "Dorice", "Dorie", "Dorine", "Doris", "Dorisa", "Dorise", "Dorita", "Doro", "Dorolice", "Dorolisa", "Dorotea", "Doroteya", "Dorothea", "Dorothee", "Dorothy", "Dorree", "Dorri", "Dorrie", "Dorris", "Dorry", "Dorthea", "Dorthy", "Dory", "Dosi", "Dot", "Doti", "Dotti", "Dottie", "Dotty", "Dre", "Dreddy", "Dredi", "Drona", "Dru", "Druci", "Drucie", "Drucill", "Drucy", "Drusi", "Drusie", "Drusilla", "Drusy", "Dulce", "Dulcea", "Dulci", "Dulcia", "Dulciana", "Dulcie", "Dulcine", "Dulcinea", "Dulcy", "Dulsea", "Dusty", "Dyan", "Dyana", "Dyane", "Dyann", "Dyanna", "Dyanne", "Dyna", "Dynah", "Eachelle", "Eada", "Eadie", "Eadith", "Ealasaid", "Eartha", "Easter", "Eba", "Ebba", "Ebonee", "Ebony", "Eda", "Eddi", "Eddie", "Eddy", "Ede", "Edee", "Edeline", "Eden", "Edi", "Edie", "Edin", "Edita", "Edith", "Editha", "Edithe", "Ediva", "Edna", "Edwina", "Edy", "Edyth", "Edythe", "Effie", "Eileen", "Eilis", "Eimile", "Eirena", "Ekaterina", "Elaina", "Elaine", "Elana", "Elane", "Elayne", "Elberta", "Elbertina", "Elbertine", "Eleanor", "Eleanora", "Eleanore", "Electra", "Eleen", "Elena", "Elene", "Eleni", "Elenore", "Eleonora", "Eleonore", "Elfie", "Elfreda", "Elfrida", "Elfrieda", "Elga", "Elianora", "Elianore", "Elicia", "Elie", "Elinor", "Elinore", "Elisa", "Elisabet", "Elisabeth", "Elisabetta", "Elise", "Elisha", "Elissa", "Elita", "Eliza", "Elizabet", "Elizabeth", "Elka", "Elke", "Ella", "Elladine", "Elle", "Ellen", "Ellene", "Ellette", "Elli", "Ellie", "Ellissa", "Elly", "Ellyn", "Ellynn", "Elmira", "Elna", "Elnora", "Elnore", "Eloisa", "Eloise", "Elonore", "Elora", "Elsa", "Elsbeth", "Else", "Elset", "Elsey", "Elsi", "Elsie", "Elsinore", "Elspeth", "Elsy", "Elva", "Elvera", "Elvina", "Elvira", "Elwira", "Elyn", "Elyse", "Elysee", "Elysha", "Elysia", "Elyssa", "Em", "Ema", "Emalee", "Emalia", "Emelda", "Emelia", "Emelina", "Emeline", "Emelita", "Emelyne", "Emera", "Emilee", "Emili", "Emilia", "Emilie", "Emiline", "Emily", "Emlyn", "Emlynn", "Emlynne", "Emma", "Emmalee", "Emmaline", "Emmalyn", "Emmalynn", "Emmalynne", "Emmeline", "Emmey", "Emmi", "Emmie", "Emmy", "Emmye", "Emogene", "Emyle", "Emylee", "Engracia", "Enid", "Enrica", "Enrichetta", "Enrika", "Enriqueta", "Eolanda", "Eolande", "Eran", "Erda", "Erena", "Erica", "Ericha", "Ericka", "Erika", "Erin", "Erina", "Erinn", "Erinna", "Erma", "Ermengarde", "Ermentrude", "Ermina", "Erminia", "Erminie", "Erna", "Ernaline", "Ernesta", "Ernestine", "Ertha", "Eryn", "Esma", "Esmaria", "Esme", "Esmeralda", "Essa", "Essie", "Essy", "Esta", "Estel", "Estele", "Estell", "Estella", "Estelle", "Ester", "Esther", "Estrella", "Estrellita", "Ethel", "Ethelda", "Ethelin", "Ethelind", "Etheline", "Ethelyn", "Ethyl", "Etta", "Etti", "Ettie", "Etty", "Eudora", "Eugenia", "Eugenie", "Eugine", "Eula", "Eulalie", "Eunice", "Euphemia", "Eustacia", "Eva", "Evaleen", "Evangelia", "Evangelin", "Evangelina", "Evangeline", "Evania", "Evanne", "Eve", "Eveleen", "Evelina", "Eveline", "Evelyn", "Evey", "Evie", "Evita", "Evonne", "Evvie", "Evvy", "Evy", "Eyde", "Eydie", "Ezmeralda", "Fae", "Faina", "Faith", "Fallon", "Fan", "Fanchette", "Fanchon", "Fancie", "Fancy", "Fanechka", "Fania", "Fanni", "Fannie", "Fanny", "Fanya", "Fara", "Farah", "Farand", "Farica", "Farra", "Farrah", "Farrand", "Faun", "Faunie", "Faustina", "Faustine", "Fawn", "Fawne", "Fawnia", "Fay", "Faydra", "Faye", "Fayette", "Fayina", "Fayre", "Fayth", "Faythe", "Federica", "Fedora", "Felecia", "Felicdad", "Felice", "Felicia", "Felicity", "Felicle", "Felipa", "Felisha", "Felita", "Feliza", "Fenelia", "Feodora", "Ferdinanda", "Ferdinande", "Fern", "Fernanda", "Fernande", "Fernandina", "Ferne", "Fey", "Fiann", "Fianna", "Fidela", "Fidelia", "Fidelity", "Fifi", "Fifine", "Filia", "Filide", "Filippa", "Fina", "Fiona", "Fionna", "Fionnula", "Fiorenze", "Fleur", "Fleurette", "Flo", "Flor", "Flora", "Florance", "Flore", "Florella", "Florence", "Florencia", "Florentia", "Florenza", "Florette", "Flori", "Floria", "Florida", "Florie", "Florina", "Florinda", "Floris", "Florri", "Florrie", "Florry", "Flory", "Flossi", "Flossie", "Flossy", "Flss", "Fran", "Francene", "Frances", "Francesca", "Francine", "Francisca", "Franciska", "Francoise", "Francyne", "Frank", "Frankie", "Franky", "Franni", "Frannie", "Franny", "Frayda", "Fred", "Freda", "Freddi", "Freddie", "Freddy", "Fredelia", "Frederica", "Fredericka", "Frederique", "Fredi", "Fredia", "Fredra", "Fredrika", "Freida", "Frieda", "Friederike", "Fulvia", "Gabbey", "Gabbi", "Gabbie", "Gabey", "Gabi", "Gabie", "Gabriel", "Gabriela", "Gabriell", "Gabriella", "Gabrielle", "Gabriellia", "Gabrila", "Gaby", "Gae", "Gael", "Gail", "Gale", "Galina", "Garland", "Garnet", "Garnette", "Gates", "Gavra", "Gavrielle", "Gay", "Gaye", "Gayel", "Gayla", "Gayle", "Gayleen", "Gaylene", "Gaynor", "Gelya", "Gena", "Gene", "Geneva", "Genevieve", "Genevra", "Genia", "Genna", "Genni", "Gennie", "Gennifer", "Genny", "Genovera", "Genvieve", "George", "Georgeanna", "Georgeanne", "Georgena", "Georgeta", "Georgetta", "Georgette", "Georgia", "Georgiana", "Georgianna", "Georgianne", "Georgie", "Georgina", "Georgine", "Geralda", "Geraldine", "Gerda", "Gerhardine", "Geri", "Gerianna", "Gerianne", "Gerladina", "Germain", "Germaine", "Germana", "Gerri", "Gerrie", "Gerrilee", "Gerry", "Gert", "Gerta", "Gerti", "Gertie", "Gertrud", "Gertruda", "Gertrude", "Gertrudis", "Gerty", "Giacinta", "Giana", "Gianina", "Gianna", "Gigi", "Gilberta", "Gilberte", "Gilbertina", "Gilbertine", "Gilda", "Gilemette", "Gill", "Gillan", "Gilli", "Gillian", "Gillie", "Gilligan", "Gilly", "Gina", "Ginelle", "Ginevra", "Ginger", "Ginni", "Ginnie", "Ginnifer", "Ginny", "Giorgia", "Giovanna", "Gipsy", "Giralda", "Gisela", "Gisele", "Gisella", "Giselle", "Giuditta", "Giulia", "Giulietta", "Giustina", "Gizela", "Glad", "Gladi", "Gladys", "Gleda", "Glen", "Glenda", "Glenine", "Glenn", "Glenna", "Glennie", "Glennis", "Glori", "Gloria", "Gloriana", "Gloriane", "Glory", "Glyn", "Glynda", "Glynis", "Glynnis", "Gnni", "Godiva", "Golda", "Goldarina", "Goldi", "Goldia", "Goldie", "Goldina", "Goldy", "Grace", "Gracia", "Gracie", "Grata", "Gratia", "Gratiana", "Gray", "Grayce", "Grazia", "Greer", "Greta", "Gretal", "Gretchen", "Grete", "Gretel", "Grethel", "Gretna", "Gretta", "Grier", "Griselda", "Grissel", "Guendolen", "Guenevere", "Guenna", "Guglielma", "Gui", "Guillema", "Guillemette", "Guinevere", "Guinna", "Gunilla", "Gus", "Gusella", "Gussi", "Gussie", "Gussy", "Gusta", "Gusti", "Gustie", "Gusty", "Gwen", "Gwendolen", "Gwendolin", "Gwendolyn", "Gweneth", "Gwenette", "Gwenneth", "Gwenni", "Gwennie", "Gwenny", "Gwenora", "Gwenore", "Gwyn", "Gwyneth", "Gwynne", "Gypsy", "Hadria", "Hailee", "Haily", "Haleigh", "Halette", "Haley", "Hali", "Halie", "Halimeda", "Halley", "Halli", "Hallie", "Hally", "Hana", "Hanna", "Hannah", "Hanni", "Hannie", "Hannis", "Hanny", "Happy", "Harlene", "Harley", "Harli", "Harlie", "Harmonia", "Harmonie", "Harmony", "Harri", "Harrie", "Harriet", "Harriett", "Harrietta", "Harriette", "Harriot", "Harriott", "Hatti", "Hattie", "Hatty", "Hayley", "Hazel", "Heath", "Heather", "Heda", "Hedda", "Heddi", "Heddie", "Hedi", "Hedvig", "Hedvige", "Hedwig", "Hedwiga", "Hedy", "Heida", "Heidi", "Heidie", "Helaina", "Helaine", "Helen", "Helen-Elizabeth", "Helena", "Helene", "Helenka", "Helga", "Helge", "Helli", "Heloise", "Helsa", "Helyn", "Hendrika", "Henka", "Henrie", "Henrieta", "Henrietta", "Henriette", "Henryetta", "Hephzibah", "Hermia", "Hermina", "Hermine", "Herminia", "Hermione", "Herta", "Hertha", "Hester", "Hesther", "Hestia", "Hetti", "Hettie", "Hetty", "Hilary", "Hilda", "Hildagard", "Hildagarde", "Hilde", "Hildegaard", "Hildegarde", "Hildy", "Hillary", "Hilliary", "Hinda", "Holli", "Hollie", "Holly", "Holly-Anne", "Hollyanne", "Honey", "Honor", "Honoria", "Hope", "Horatia", "Hortense", "Hortensia", "Hulda", "Hyacinth", "Hyacintha", "Hyacinthe", "Hyacinthia", "Hyacinthie", "Hynda", "Ianthe", "Ibbie", "Ibby", "Ida", "Idalia", "Idalina", "Idaline", "Idell", "Idelle", "Idette", "Ileana", "Ileane", "Ilene", "Ilise", "Ilka", "Illa", "Ilsa", "Ilse", "Ilysa", "Ilyse", "Ilyssa", "Imelda", "Imogen", "Imogene", "Imojean", "Ina", "Indira", "Ines", "Inesita", "Inessa", "Inez", "Inga", "Ingaberg", "Ingaborg", "Inge", "Ingeberg", "Ingeborg", "Inger", "Ingrid", "Ingunna", "Inna", "Iolande", "Iolanthe", "Iona", "Iormina", "Ira", "Irena", "Irene", "Irina", "Iris", "Irita", "Irma", "Isa", "Isabel", "Isabelita", "Isabella", "Isabelle", "Isadora", "Isahella", "Iseabal", "Isidora", "Isis", "Isobel", "Issi", "Issie", "Issy", "Ivett", "Ivette", "Ivie", "Ivonne", "Ivory", "Ivy", "Izabel", "Jacenta", "Jacinda", "Jacinta", "Jacintha", "Jacinthe", "Jackelyn", "Jacki", "Jackie", "Jacklin", "Jacklyn", "Jackquelin", "Jackqueline", "Jacky", "Jaclin", "Jaclyn", "Jacquelin", "Jacqueline", "Jacquelyn", "Jacquelynn", "Jacquenetta", "Jacquenette", "Jacquetta", "Jacquette", "Jacqui", "Jacquie", "Jacynth", "Jada", "Jade", "Jaime", "Jaimie", "Jaine", "Jami", "Jamie", "Jamima", "Jammie", "Jan", "Jana", "Janaya", "Janaye", "Jandy", "Jane", "Janean", "Janeczka", "Janeen", "Janel", "Janela", "Janella", "Janelle", "Janene", "Janenna", "Janessa", "Janet", "Janeta", "Janetta", "Janette", "Janeva", "Janey", "Jania", "Janice", "Janie", "Janifer", "Janina", "Janine", "Janis", "Janith", "Janka", "Janna", "Jannel", "Jannelle", "Janot", "Jany", "Jaquelin", "Jaquelyn", "Jaquenetta", "Jaquenette", "Jaquith", "Jasmin", "Jasmina", "Jasmine", "Jayme", "Jaymee", "Jayne", "Jaynell", "Jazmin", "Jean", "Jeana", "Jeane", "Jeanelle", "Jeanette", "Jeanie", "Jeanine", "Jeanna", "Jeanne", "Jeannette", "Jeannie", "Jeannine", "Jehanna", "Jelene", "Jemie", "Jemima", "Jemimah", "Jemmie", "Jemmy", "Jen", "Jena", "Jenda", "Jenelle", "Jeni", "Jenica", "Jeniece", "Jenifer", "Jeniffer", "Jenilee", "Jenine", "Jenn", "Jenna", "Jennee", "Jennette", "Jenni", "Jennica", "Jennie", "Jennifer", "Jennilee", "Jennine", "Jenny", "Jeralee", "Jere", "Jeri", "Jermaine", "Jerrie", "Jerrilee", "Jerrilyn", "Jerrine", "Jerry", "Jerrylee", "Jess", "Jessa", "Jessalin", "Jessalyn", "Jessamine", "Jessamyn", "Jesse", "Jesselyn", "Jessi", "Jessica", "Jessie", "Jessika", "Jessy", "Jewel", "Jewell", "Jewelle", "Jill", "Jillana", "Jillane", "Jillayne", "Jilleen", "Jillene", "Jilli", "Jillian", "Jillie", "Jilly", "Jinny", "Jo", "Jo Ann", "Jo-Ann", "Jo-Anne", "Joan", "Joana", "Joane", "Joanie", "Joann", "Joanna", "Joanne", "Joannes", "Jobey", "Jobi", "Jobie", "Jobina", "Joby", "Jobye", "Jobyna", "Jocelin", "Joceline", "Jocelyn", "Jocelyne", "Jodee", "Jodi", "Jodie", "Jody", "Joeann", "Joela", "Joelie", "Joell", "Joella", "Joelle", "Joellen", "Joelly", "Joellyn", "Joelynn", "Joete", "Joey", "Johanna", "Johannah", "Johna", "Johnath", "Johnette", "Johnna", "Joice", "Jojo", "Jolee", "Joleen", "Jolene", "Joletta", "Joli", "Jolie", "Joline", "Joly", "Jolyn", "Jolynn", "Jonell", "Joni", "Jonie", "Jonis", "Jordain", "Jordan", "Jordana", "Jordanna", "Jorey", "Jori", "Jorie", "Jorrie", "Jorry", "Joscelin", "Josee", "Josefa", "Josefina", "Josepha", "Josephina", "Josephine", "Josey", "Josi", "Josie", "Josselyn", "Josy", "Jourdan", "Joy", "Joya", "Joyan", "Joyann", "Joyce", "Joycelin", "Joye", "Jsandye", "Juana", "Juanita", "Judi", "Judie", "Judith", "Juditha", "Judy", "Judye", "Juieta", "Julee", "Juli", "Julia", "Juliana", "Juliane", "Juliann", "Julianna", "Julianne", "Julie", "Julienne", "Juliet", "Julieta", "Julietta", "Juliette", "Julina", "Juline", "Julissa", "Julita", "June", "Junette", "Junia", "Junie", "Junina", "Justina", "Justine", "Justinn", "Jyoti", "Kacey", "Kacie", "Kacy", "Kaela", "Kai", "Kaia", "Kaila", "Kaile", "Kailey", "Kaitlin", "Kaitlyn", "Kaitlynn", "Kaja", "Kakalina", "Kala", "Kaleena", "Kali", "Kalie", "Kalila", "Kalina", "Kalinda", "Kalindi", "Kalli", "Kally", "Kameko", "Kamila", "Kamilah", "Kamillah", "Kandace", "Kandy", "Kania", "Kanya", "Kara", "Kara-Lynn", "Karalee", "Karalynn", "Kare", "Karee", "Karel", "Karen", "Karena", "Kari", "Karia", "Karie", "Karil", "Karilynn", "Karin", "Karina", "Karine", "Kariotta", "Karisa", "Karissa", "Karita", "Karla", "Karlee", "Karleen", "Karlen", "Karlene", "Karlie", "Karlotta", "Karlotte", "Karly", "Karlyn", "Karmen", "Karna", "Karol", "Karola", "Karole", "Karolina", "Karoline", "Karoly", "Karon", "Karrah", "Karrie", "Karry", "Kary", "Karyl", "Karylin", "Karyn", "Kasey", "Kass", "Kassandra", "Kassey", "Kassi", "Kassia", "Kassie", "Kat", "Kata", "Katalin", "Kate", "Katee", "Katerina", "Katerine", "Katey", "Kath", "Katha", "Katharina", "Katharine", "Katharyn", "Kathe", "Katherina", "Katherine", "Katheryn", "Kathi", "Kathie", "Kathleen", "Kathlin", "Kathrine", "Kathryn", "Kathryne", "Kathy", "Kathye", "Kati", "Katie", "Katina", "Katine", "Katinka", "Katleen", "Katlin", "Katrina", "Katrine", "Katrinka", "Katti", "Kattie", "Katuscha", "Katusha", "Katy", "Katya", "Kay", "Kaycee", "Kaye", "Kayla", "Kayle", "Kaylee", "Kayley", "Kaylil", "Kaylyn", "Keeley", "Keelia", "Keely", "Kelcey", "Kelci", "Kelcie", "Kelcy", "Kelila", "Kellen", "Kelley", "Kelli", "Kellia", "Kellie", "Kellina", "Kellsie", "Kelly", "Kellyann", "Kelsey", "Kelsi", "Kelsy", "Kendra", "Kendre", "Kenna", "Keri", "Keriann", "Kerianne", "Kerri", "Kerrie", "Kerrill", "Kerrin", "Kerry", "Kerstin", "Kesley", "Keslie", "Kessia", "Kessiah", "Ketti", "Kettie", "Ketty", "Kevina", "Kevyn", "Ki", "Kiah", "Kial", "Kiele", "Kiersten", "Kikelia", "Kiley", "Kim", "Kimberlee", "Kimberley", "Kimberli", "Kimberly", "Kimberlyn", "Kimbra", "Kimmi", "Kimmie", "Kimmy", "Kinna", "Kip", "Kipp", "Kippie", "Kippy", "Kira", "Kirbee", "Kirbie", "Kirby", "Kiri", "Kirsten", "Kirsteni", "Kirsti", "Kirstin", "Kirstyn", "Kissee", "Kissiah", "Kissie", "Kit", "Kitti", "Kittie", "Kitty", "Kizzee", "Kizzie", "Klara", "Klarika", "Klarrisa", "Konstance", "Konstanze", "Koo", "Kora", "Koral", "Koralle", "Kordula", "Kore", "Korella", "Koren", "Koressa", "Kori", "Korie", "Korney", "Korrie", "Korry", "Kris", "Krissie", "Krissy", "Krista", "Kristal", "Kristan", "Kriste", "Kristel", "Kristen", "Kristi", "Kristien", "Kristin", "Kristina", "Kristine", "Kristy", "Kristyn", "Krysta", "Krystal", "Krystalle", "Krystle", "Krystyna", "Kyla", "Kyle", "Kylen", "Kylie", "Kylila", "Kylynn", "Kym", "Kynthia", "Kyrstin", "La Verne", "Lacee", "Lacey", "Lacie", "Lacy", "Ladonna", "Laetitia", "Laina", "Lainey", "Lana", "Lanae", "Lane", "Lanette", "Laney", "Lani", "Lanie", "Lanita", "Lanna", "Lanni", "Lanny", "Lara", "Laraine", "Lari", "Larina", "Larine", "Larisa", "Larissa", "Lark", "Laryssa", "Latashia", "Latia", "Latisha", "Latrena", "Latrina", "Laura", "Lauraine", "Laural", "Lauralee", "Laure", "Lauree", "Laureen", "Laurel", "Laurella", "Lauren", "Laurena", "Laurene", "Lauretta", "Laurette", "Lauri", "Laurianne", "Laurice", "Laurie", "Lauryn", "Lavena", "Laverna", "Laverne", "Lavina", "Lavinia", "Lavinie", "Layla", "Layne", "Layney", "Lea", "Leah", "Leandra", "Leann", "Leanna", "Leanor", "Leanora", "Lebbie", "Leda", "Lee", "Leeann", "Leeanne", "Leela", "Leelah", "Leena", "Leesa", "Leese", "Legra", "Leia", "Leigh", "Leigha", "Leila", "Leilah", "Leisha", "Lela", "Lelah", "Leland", "Lelia", "Lena", "Lenee", "Lenette", "Lenka", "Lenna", "Lenora", "Lenore", "Leodora", "Leoine", "Leola", "Leoline", "Leona", "Leonanie", "Leone", "Leonelle", "Leonie", "Leonora", "Leonore", "Leontine", "Leontyne", "Leora", "Leshia", "Lesley", "Lesli", "Leslie", "Lesly", "Lesya", "Leta", "Lethia", "Leticia", "Letisha", "Letitia", "Letizia", "Letta", "Letti", "Lettie", "Letty", "Lexi", "Lexie", "Lexine", "Lexis", "Lexy", "Leyla", "Lezlie", "Lia", "Lian", "Liana", "Liane", "Lianna", "Lianne", "Lib", "Libbey", "Libbi", "Libbie", "Libby", "Licha", "Lida", "Lidia", "Liesa", "Lil", "Lila", "Lilah", "Lilas", "Lilia", "Lilian", "Liliane", "Lilias", "Lilith", "Lilla", "Lilli", "Lillian", "Lillis", "Lilllie", "Lilly", "Lily", "Lilyan", "Lin", "Lina", "Lind", "Linda", "Lindi", "Lindie", "Lindsay", "Lindsey", "Lindsy", "Lindy", "Linea", "Linell", "Linet", "Linette", "Linn", "Linnea", "Linnell", "Linnet", "Linnie", "Linzy", "Lira", "Lisa", "Lisabeth", "Lisbeth", "Lise", "Lisetta", "Lisette", "Lisha", "Lishe", "Lissa", "Lissi", "Lissie", "Lissy", "Lita", "Liuka", "Liv", "Liva", "Livia", "Livvie", "Livvy", "Livvyy", "Livy", "Liz", "Liza", "Lizabeth", "Lizbeth", "Lizette", "Lizzie", "Lizzy", "Loella", "Lois", "Loise", "Lola", "Loleta", "Lolita", "Lolly", "Lona", "Lonee", "Loni", "Lonna", "Lonni", "Lonnie", "Lora", "Lorain", "Loraine", "Loralee", "Loralie", "Loralyn", "Loree", "Loreen", "Lorelei", "Lorelle", "Loren", "Lorena", "Lorene", "Lorenza", "Loretta", "Lorette", "Lori", "Loria", "Lorianna", "Lorianne", "Lorie", "Lorilee", "Lorilyn", "Lorinda", "Lorine", "Lorita", "Lorna", "Lorne", "Lorraine", "Lorrayne", "Lorri", "Lorrie", "Lorrin", "Lorry", "Lory", "Lotta", "Lotte", "Lotti", "Lottie", "Lotty", "Lou", "Louella", "Louisa", "Louise", "Louisette", "Loutitia", "Lu", "Luce", "Luci", "Lucia", "Luciana", "Lucie", "Lucienne", "Lucila", "Lucilia", "Lucille", "Lucina", "Lucinda", "Lucine", "Lucita", "Lucky", "Lucretia", "Lucy", "Ludovika", "Luella", "Luelle", "Luisa", "Luise", "Lula", "Lulita", "Lulu", "Lura", "Lurette", "Lurleen", "Lurlene", "Lurline", "Lusa", "Luz", "Lyda", "Lydia", "Lydie", "Lyn", "Lynda", "Lynde", "Lyndel", "Lyndell", "Lyndsay", "Lyndsey", "Lyndsie", "Lyndy", "Lynea", "Lynelle", "Lynett", "Lynette", "Lynn", "Lynna", "Lynne", "Lynnea", "Lynnell", "Lynnelle", "Lynnet", "Lynnett", "Lynnette", "Lynsey", "Lyssa", "Mab", "Mabel", "Mabelle", "Mable", "Mada", "Madalena", "Madalyn", "Maddalena", "Maddi", "Maddie", "Maddy", "Madel", "Madelaine", "Madeleine", "Madelena", "Madelene", "Madelin", "Madelina", "Madeline", "Madella", "Madelle", "Madelon", "Madelyn", "Madge", "Madlen", "Madlin", "Madonna", "Mady", "Mae", "Maegan", "Mag", "Magda", "Magdaia", "Magdalen", "Magdalena", "Magdalene", "Maggee", "Maggi", "Maggie", "Maggy", "Mahala", "Mahalia", "Maia", "Maible", "Maiga", "Maighdiln", "Mair", "Maire", "Maisey", "Maisie", "Maitilde", "Mala", "Malanie", "Malena", "Malia", "Malina", "Malinda", "Malinde", "Malissa", "Malissia", "Mallissa", "Mallorie", "Mallory", "Malorie", "Malory", "Malva", "Malvina", "Malynda", "Mame", "Mamie", "Manda", "Mandi", "Mandie", "Mandy", "Manon", "Manya", "Mara", "Marabel", "Marcela", "Marcelia", "Marcella", "Marcelle", "Marcellina", "Marcelline", "Marchelle", "Marci", "Marcia", "Marcie", "Marcile", "Marcille", "Marcy", "Mareah", "Maren", "Marena", "Maressa", "Marga", "Margalit", "Margalo", "Margaret", "Margareta", "Margarete", "Margaretha", "Margarethe", "Margaretta", "Margarette", "Margarita", "Margaux", "Marge", "Margeaux", "Margery", "Marget", "Margette", "Margi", "Margie", "Margit", "Margo", "Margot", "Margret", "Marguerite", "Margy", "Mari", "Maria", "Mariam", "Marian", "Mariana", "Mariann", "Marianna", "Marianne", "Maribel", "Maribelle", "Maribeth", "Marice", "Maridel", "Marie", "Marie-Ann", "Marie-Jeanne", "Marieann", "Mariejeanne", "Mariel", "Mariele", "Marielle", "Mariellen", "Marietta", "Mariette", "Marigold", "Marijo", "Marika", "Marilee", "Marilin", "Marillin", "Marilyn", "Marin", "Marina", "Marinna", "Marion", "Mariquilla", "Maris", "Marisa", "Mariska", "Marissa", "Marita", "Maritsa", "Mariya", "Marj", "Marja", "Marje", "Marji", "Marjie", "Marjorie", "Marjory", "Marjy", "Marketa", "Marla", "Marlane", "Marleah", "Marlee", "Marleen", "Marlena", "Marlene", "Marley", "Marlie", "Marline", "Marlo", "Marlyn", "Marna", "Marne", "Marney", "Marni", "Marnia", "Marnie", "Marquita", "Marrilee", "Marris", "Marrissa", "Marsha", "Marsiella", "Marta", "Martelle", "Martguerita", "Martha", "Marthe", "Marthena", "Marti", "Martica", "Martie", "Martina", "Martita", "Marty", "Martynne", "Mary", "Marya", "Maryann", "Maryanna", "Maryanne", "Marybelle", "Marybeth", "Maryellen", "Maryjane", "Maryjo", "Maryl", "Marylee", "Marylin", "Marylinda", "Marylou", "Marylynne", "Maryrose", "Marys", "Marysa", "Masha", "Matelda", "Mathilda", "Mathilde", "Matilda", "Matilde", "Matti", "Mattie", "Matty", "Maud", "Maude", "Maudie", "Maura", "Maure", "Maureen", "Maureene", "Maurene", "Maurine", "Maurise", "Maurita", "Maurizia", "Mavis", "Mavra", "Max", "Maxi", "Maxie", "Maxine", "Maxy", "May", "Maybelle", "Maye", "Mead", "Meade", "Meagan", "Meaghan", "Meara", "Mechelle", "Meg", "Megan", "Megen", "Meggi", "Meggie", "Meggy", "Meghan", "Meghann", "Mehetabel", "Mei", "Mel", "Mela", "Melamie", "Melania", "Melanie", "Melantha", "Melany", "Melba", "Melesa", "Melessa", "Melicent", "Melina", "Melinda", "Melinde", "Melisa", "Melisande", "Melisandra", "Melisenda", "Melisent", "Melissa", "Melisse", "Melita", "Melitta", "Mella", "Melli", "Mellicent", "Mellie", "Mellisa", "Mellisent", "Melloney", "Melly", "Melodee", "Melodie", "Melody", "Melonie", "Melony", "Melosa", "Melva", "Mercedes", "Merci", "Mercie", "Mercy", "Meredith", "Meredithe", "Meridel", "Meridith", "Meriel", "Merilee", "Merilyn", "Meris", "Merissa", "Merl", "Merla", "Merle", "Merlina", "Merline", "Merna", "Merola", "Merralee", "Merridie", "Merrie", "Merrielle", "Merrile", "Merrilee", "Merrili", "Merrill", "Merrily", "Merry", "Mersey", "Meryl", "Meta", "Mia", "Micaela", "Michaela", "Michaelina", "Michaeline", "Michaella", "Michal", "Michel", "Michele", "Michelina", "Micheline", "Michell", "Michelle", "Micki", "Mickie", "Micky", "Midge", "Mignon", "Mignonne", "Miguela", "Miguelita", "Mikaela", "Mil", "Mildred", "Mildrid", "Milena", "Milicent", "Milissent", "Milka", "Milli", "Millicent", "Millie", "Millisent", "Milly", "Milzie", "Mimi", "Min", "Mina", "Minda", "Mindy", "Minerva", "Minetta", "Minette", "Minna", "Minnaminnie", "Minne", "Minni", "Minnie", "Minnnie", "Minny", "Minta", "Miof Mela", "Miquela", "Mira", "Mirabel", "Mirabella", "Mirabelle", "Miran", "Miranda", "Mireielle", "Mireille", "Mirella", "Mirelle", "Miriam", "Mirilla", "Mirna", "Misha", "Missie", "Missy", "Misti", "Misty", "Mitzi", "Modesta", "Modestia", "Modestine", "Modesty", "Moina", "Moira", "Moll", "Mollee", "Molli", "Mollie", "Molly", "Mommy", "Mona", "Monah", "Monica", "Monika", "Monique", "Mora", "Moreen", "Morena", "Morgan", "Morgana", "Morganica", "Morganne", "Morgen", "Moria", "Morissa", "Morna", "Moselle", "Moyna", "Moyra", "Mozelle", "Muffin", "Mufi", "Mufinella", "Muire", "Mureil", "Murial", "Muriel", "Murielle", "Myra", "Myrah", "Myranda", "Myriam", "Myrilla", "Myrle", "Myrlene", "Myrna", "Myrta", "Myrtia", "Myrtice", "Myrtie", "Myrtle", "Nada", "Nadean", "Nadeen", "Nadia", "Nadine", "Nadiya", "Nady", "Nadya", "Nalani", "Nan", "Nana", "Nananne", "Nance", "Nancee", "Nancey", "Nanci", "Nancie", "Nancy", "Nanete", "Nanette", "Nani", "Nanice", "Nanine", "Nannette", "Nanni", "Nannie", "Nanny", "Nanon", "Naoma", "Naomi", "Nara", "Nari", "Nariko", "Nat", "Nata", "Natala", "Natalee", "Natalie", "Natalina", "Nataline", "Natalya", "Natasha", "Natassia", "Nathalia", "Nathalie", "Natividad", "Natka", "Natty", "Neala", "Neda", "Nedda", "Nedi", "Neely", "Neila", "Neile", "Neilla", "Neille", "Nelia", "Nelie", "Nell", "Nelle", "Nelli", "Nellie", "Nelly", "Nerissa", "Nerita", "Nert", "Nerta", "Nerte", "Nerti", "Nertie", "Nerty", "Nessa", "Nessi", "Nessie", "Nessy", "Nesta", "Netta", "Netti", "Nettie", "Nettle", "Netty", "Nevsa", "Neysa", "Nichol", "Nichole", "Nicholle", "Nicki", "Nickie", "Nicky", "Nicol", "Nicola", "Nicole", "Nicolea", "Nicolette", "Nicoli", "Nicolina", "Nicoline", "Nicolle", "Nikaniki", "Nike", "Niki", "Nikki", "Nikkie", "Nikoletta", "Nikolia", "Nina", "Ninetta", "Ninette", "Ninnetta", "Ninnette", "Ninon", "Nissa", "Nisse", "Nissie", "Nissy", "Nita", "Nixie", "Noami", "Noel", "Noelani", "Noell", "Noella", "Noelle", "Noellyn", "Noelyn", "Noemi", "Nola", "Nolana", "Nolie", "Nollie", "Nomi", "Nona", "Nonah", "Noni", "Nonie", "Nonna", "Nonnah", "Nora", "Norah", "Norean", "Noreen", "Norene", "Norina", "Norine", "Norma", "Norri", "Norrie", "Norry", "Novelia", "Nydia", "Nyssa", "Octavia", "Odele", "Odelia", "Odelinda", "Odella", "Odelle", "Odessa", "Odetta", "Odette", "Odilia", "Odille", "Ofelia", "Ofella", "Ofilia", "Ola", "Olenka", "Olga", "Olia", "Olimpia", "Olive", "Olivette", "Olivia", "Olivie", "Oliy", "Ollie", "Olly", "Olva", "Olwen", "Olympe", "Olympia", "Olympie", "Ondrea", "Oneida", "Onida", "Oona", "Opal", "Opalina", "Opaline", "Ophelia", "Ophelie", "Ora", "Oralee", "Oralia", "Oralie", "Oralla", "Oralle", "Orel", "Orelee", "Orelia", "Orelie", "Orella", "Orelle", "Oriana", "Orly", "Orsa", "Orsola", "Ortensia", "Otha", "Othelia", "Othella", "Othilia", "Othilie", "Ottilie", "Page", "Paige", "Paloma", "Pam", "Pamela", "Pamelina", "Pamella", "Pammi", "Pammie", "Pammy", "Pandora", "Pansie", "Pansy", "Paola", "Paolina", "Papagena", "Pat", "Patience", "Patrica", "Patrice", "Patricia", "Patrizia", "Patsy", "Patti", "Pattie", "Patty", "Paula", "Paule", "Pauletta", "Paulette", "Pauli", "Paulie", "Paulina", "Pauline", "Paulita", "Pauly", "Pavia", "Pavla", "Pearl", "Pearla", "Pearle", "Pearline", "Peg", "Pegeen", "Peggi", "Peggie", "Peggy", "Pen", "Penelopa", "Penelope", "Penni", "Pennie", "Penny", "Pepi", "Pepita", "Peri", "Peria", "Perl", "Perla", "Perle", "Perri", "Perrine", "Perry", "Persis", "Pet", "Peta", "Petra", "Petrina", "Petronella", "Petronia", "Petronilla", "Petronille", "Petunia", "Phaedra", "Phaidra", "Phebe", "Phedra", "Phelia", "Phil", "Philipa", "Philippa", "Philippe", "Philippine", "Philis", "Phillida", "Phillie", "Phillis", "Philly", "Philomena", "Phoebe", "Phylis", "Phyllida", "Phyllis", "Phyllys", "Phylys", "Pia", "Pier", "Pierette", "Pierrette", "Pietra", "Piper", "Pippa", "Pippy", "Polly", "Pollyanna", "Pooh", "Poppy", "Portia", "Pris", "Prisca", "Priscella", "Priscilla", "Prissie", "Pru", "Prudence", "Prudi", "Prudy", "Prue", "Queenie", "Quentin", "Querida", "Quinn", "Quinta", "Quintana", "Quintilla", "Quintina", "Rachael", "Rachel", "Rachele", "Rachelle", "Rae", "Raeann", "Raf", "Rafa", "Rafaela", "Rafaelia", "Rafaelita", "Rahal", "Rahel", "Raina", "Raine", "Rakel", "Ralina", "Ramona", "Ramonda", "Rana", "Randa", "Randee", "Randene", "Randi", "Randie", "Randy", "Ranee", "Rani", "Rania", "Ranice", "Ranique", "Ranna", "Raphaela", "Raquel", "Raquela", "Rasia", "Rasla", "Raven", "Ray", "Raychel", "Raye", "Rayna", "Raynell", "Rayshell", "Rea", "Reba", "Rebbecca", "Rebe", "Rebeca", "Rebecca", "Rebecka", "Rebeka", "Rebekah", "Rebekkah", "Ree", "Reeba", "Reena", "Reeta", "Reeva", "Regan", "Reggi", "Reggie", "Regina", "Regine", "Reiko", "Reina", "Reine", "Remy", "Rena", "Renae", "Renata", "Renate", "Rene", "Renee", "Renell", "Renelle", "Renie", "Rennie", "Reta", "Retha", "Revkah", "Rey", "Reyna", "Rhea", "Rheba", "Rheta", "Rhetta", "Rhiamon", "Rhianna", "Rhianon", "Rhoda", "Rhodia", "Rhodie", "Rhody", "Rhona", "Rhonda", "Riane", "Riannon", "Rianon", "Rica", "Ricca", "Rici", "Ricki", "Rickie", "Ricky", "Riki", "Rikki", "Rina", "Risa", "Rita", "Riva", "Rivalee", "Rivi", "Rivkah", "Rivy", "Roana", "Roanna", "Roanne", "Robbi", "Robbie", "Robbin", "Robby", "Robbyn", "Robena", "Robenia", "Roberta", "Robin", "Robina", "Robinet", "Robinett", "Robinetta", "Robinette", "Robinia", "Roby", "Robyn", "Roch", "Rochell", "Rochella", "Rochelle", "Rochette", "Roda", "Rodi", "Rodie", "Rodina", "Rois", "Romola", "Romona", "Romonda", "Romy", "Rona", "Ronalda", "Ronda", "Ronica", "Ronna", "Ronni", "Ronnica", "Ronnie", "Ronny", "Roobbie", "Rora", "Rori", "Rorie", "Rory", "Ros", "Rosa", "Rosabel", "Rosabella", "Rosabelle", "Rosaleen", "Rosalia", "Rosalie", "Rosalind", "Rosalinda", "Rosalinde", "Rosaline", "Rosalyn", "Rosalynd", "Rosamond", "Rosamund", "Rosana", "Rosanna", "Rosanne", "Rose", "Roseann", "Roseanna", "Roseanne", "Roselia", "Roselin", "Roseline", "Rosella", "Roselle", "Rosemaria", "Rosemarie", "Rosemary", "Rosemonde", "Rosene", "Rosetta", "Rosette", "Roshelle", "Rosie", "Rosina", "Rosita", "Roslyn", "Rosmunda", "Rosy", "Row", "Rowe", "Rowena", "Roxana", "Roxane", "Roxanna", "Roxanne", "Roxi", "Roxie", "Roxine", "Roxy", "Roz", "Rozalie", "Rozalin", "Rozamond", "Rozanna", "Rozanne", "Roze", "Rozele", "Rozella", "Rozelle", "Rozina", "Rubetta", "Rubi", "Rubia", "Rubie", "Rubina", "Ruby", "Ruperta", "Ruth", "Ruthann", "Ruthanne", "Ruthe", "Ruthi", "Ruthie", "Ruthy", "Ryann", "Rycca", "Saba", "Sabina", "Sabine", "Sabra", "Sabrina", "Sacha", "Sada", "Sadella", "Sadie", "Sadye", "Saidee", "Sal", "Salaidh", "Sallee", "Salli", "Sallie", "Sally", "Sallyann", "Sallyanne", "Saloma", "Salome", "Salomi", "Sam", "Samantha", "Samara", "Samaria", "Sammy", "Sande", "Sandi", "Sandie", "Sandra", "Sandy", "Sandye", "Sapphira", "Sapphire", "Sara", "Sara-Ann", "Saraann", "Sarah", "Sarajane", "Saree", "Sarena", "Sarene", "Sarette", "Sari", "Sarina", "Sarine", "Sarita", "Sascha", "Sasha", "Sashenka", "Saudra", "Saundra", "Savina", "Sayre", "Scarlet", "Scarlett", "Sean", "Seana", "Seka", "Sela", "Selena", "Selene", "Selestina", "Selia", "Selie", "Selina", "Selinda", "Seline", "Sella", "Selle", "Selma", "Sena", "Sephira", "Serena", "Serene", "Shae", "Shaina", "Shaine", "Shalna", "Shalne", "Shana", "Shanda", "Shandee", "Shandeigh", "Shandie", "Shandra", "Shandy", "Shane", "Shani", "Shanie", "Shanna", "Shannah", "Shannen", "Shannon", "Shanon", "Shanta", "Shantee", "Shara", "Sharai", "Shari", "Sharia", "Sharity", "Sharl", "Sharla", "Sharleen", "Sharlene", "Sharline", "Sharon", "Sharona", "Sharron", "Sharyl", "Shaun", "Shauna", "Shawn", "Shawna", "Shawnee", "Shay", "Shayla", "Shaylah", "Shaylyn", "Shaylynn", "Shayna", "Shayne", "Shea", "Sheba", "Sheela", "Sheelagh", "Sheelah", "Sheena", "Sheeree", "Sheila", "Sheila-Kathryn", "Sheilah", "Shel", "Shela", "Shelagh", "Shelba", "Shelbi", "Shelby", "Shelia", "Shell", "Shelley", "Shelli", "Shellie", "Shelly", "Shena", "Sher", "Sheree", "Sheri", "Sherie", "Sherill", "Sherilyn", "Sherline", "Sherri", "Sherrie", "Sherry", "Sherye", "Sheryl", "Shina", "Shir", "Shirl", "Shirlee", "Shirleen", "Shirlene", "Shirley", "Shirline", "Shoshana", "Shoshanna", "Siana", "Sianna", "Sib", "Sibbie", "Sibby", "Sibeal", "Sibel", "Sibella", "Sibelle", "Sibilla", "Sibley", "Sibyl", "Sibylla", "Sibylle", "Sidoney", "Sidonia", "Sidonnie", "Sigrid", "Sile", "Sileas", "Silva", "Silvana", "Silvia", "Silvie", "Simona", "Simone", "Simonette", "Simonne", "Sindee", "Siobhan", "Sioux", "Siouxie", "Sisely", "Sisile", "Sissie", "Sissy", "Siusan", "Sofia", "Sofie", "Sondra", "Sonia", "Sonja", "Sonni", "Sonnie", "Sonnnie", "Sonny", "Sonya", "Sophey", "Sophi", "Sophia", "Sophie", "Sophronia", "Sorcha", "Sosanna", "Stace", "Stacee", "Stacey", "Staci", "Stacia", "Stacie", "Stacy", "Stafani", "Star", "Starla", "Starlene", "Starlin", "Starr", "Stefa", "Stefania", "Stefanie", "Steffane", "Steffi", "Steffie", "Stella", "Stepha", "Stephana", "Stephani", "Stephanie", "Stephannie", "Stephenie", "Stephi", "Stephie", "Stephine", "Stesha", "Stevana", "Stevena", "Stoddard", "Storm", "Stormi", "Stormie", "Stormy", "Sue", "Suellen", "Sukey", "Suki", "Sula", "Sunny", "Sunshine", "Susan", "Susana", "Susanetta", "Susann", "Susanna", "Susannah", "Susanne", "Susette", "Susi", "Susie", "Susy", "Suzann", "Suzanna", "Suzanne", "Suzette", "Suzi", "Suzie", "Suzy", "Sybil", "Sybila", "Sybilla", "Sybille", "Sybyl", "Sydel", "Sydelle", "Sydney", "Sylvia", "Tabatha", "Tabbatha", "Tabbi", "Tabbie", "Tabbitha", "Tabby", "Tabina", "Tabitha", "Taffy", "Talia", "Tallia", "Tallie", "Tallou", "Tallulah", "Tally", "Talya", "Talyah", "Tamar", "Tamara", "Tamarah", "Tamarra", "Tamera", "Tami", "Tamiko", "Tamma", "Tammara", "Tammi", "Tammie", "Tammy", "Tamqrah", "Tamra", "Tana", "Tandi", "Tandie", "Tandy", "Tanhya", "Tani", "Tania", "Tanitansy", "Tansy", "Tanya", "Tara", "Tarah", "Tarra", "Tarrah", "Taryn", "Tasha", "Tasia", "Tate", "Tatiana", "Tatiania", "Tatum", "Tawnya", "Tawsha", "Ted", "Tedda", "Teddi", "Teddie", "Teddy", "Tedi", "Tedra", "Teena", "TEirtza", "Teodora", "Tera", "Teresa", "Terese", "Teresina", "Teresita", "Teressa", "Teri", "Teriann", "Terra", "Terri", "Terrie", "Terrijo", "Terry", "Terrye", "Tersina", "Terza", "Tess", "Tessa", "Tessi", "Tessie", "Tessy", "Thalia", "Thea", "Theadora", "Theda", "Thekla", "Thelma", "Theo", "Theodora", "Theodosia", "Theresa", "Therese", "Theresina", "Theresita", "Theressa", "Therine", "Thia", "Thomasa", "Thomasin", "Thomasina", "Thomasine", "Tiena", "Tierney", "Tiertza", "Tiff", "Tiffani", "Tiffanie", "Tiffany", "Tiffi", "Tiffie", "Tiffy", "Tilda", "Tildi", "Tildie", "Tildy", "Tillie", "Tilly", "Tim", "Timi", "Timmi", "Timmie", "Timmy", "Timothea", "Tina", "Tine", "Tiphani", "Tiphanie", "Tiphany", "Tish", "Tisha", "Tobe", "Tobey", "Tobi", "Toby", "Tobye", "Toinette", "Toma", "Tomasina", "Tomasine", "Tomi", "Tommi", "Tommie", "Tommy", "Toni", "Tonia", "Tonie", "Tony", "Tonya", "Tonye", "Tootsie", "Torey", "Tori", "Torie", "Torrie", "Tory", "Tova", "Tove", "Tracee", "Tracey", "Traci", "Tracie", "Tracy", "Trenna", "Tresa", "Trescha", "Tressa", "Tricia", "Trina", "Trish", "Trisha", "Trista", "Trix", "Trixi", "Trixie", "Trixy", "Truda", "Trude", "Trudey", "Trudi", "Trudie", "Trudy", "Trula", "Tuesday", "Twila", "Twyla", "Tybi", "Tybie", "Tyne", "Ula", "Ulla", "Ulrica", "Ulrika", "Ulrikaumeko", "Ulrike", "Umeko", "Una", "Ursa", "Ursala", "Ursola", "Ursula", "Ursulina", "Ursuline", "Uta", "Val", "Valaree", "Valaria", "Vale", "Valeda", "Valencia", "Valene", "Valenka", "Valentia", "Valentina", "Valentine", "Valera", "Valeria", "Valerie", "Valery", "Valerye", "Valida", "Valina", "Valli", "Vallie", "Vally", "Valma", "Valry", "Van", "Vanda", "Vanessa", "Vania", "Vanna", "Vanni", "Vannie", "Vanny", "Vanya", "Veda", "Velma", "Velvet", "Venita", "Venus", "Vera", "Veradis", "Vere", "Verena", "Verene", "Veriee", "Verile", "Verina", "Verine", "Verla", "Verna", "Vernice", "Veronica", "Veronika", "Veronike", "Veronique", "Vevay", "Vi", "Vicki", "Vickie", "Vicky", "Victoria", "Vida", "Viki", "Vikki", "Vikky", "Vilhelmina", "Vilma", "Vin", "Vina", "Vinita", "Vinni", "Vinnie", "Vinny", "Viola", "Violante", "Viole", "Violet", "Violetta", "Violette", "Virgie", "Virgina", "Virginia", "Virginie", "Vita", "Vitia", "Vitoria", "Vittoria", "Viv", "Viva", "Vivi", "Vivia", "Vivian", "Viviana", "Vivianna", "Vivianne", "Vivie", "Vivien", "Viviene", "Vivienne", "Viviyan", "Vivyan", "Vivyanne", "Vonni", "Vonnie", "Vonny", "Vyky", "Wallie", "Wallis", "Walliw", "Wally", "Waly", "Wanda", "Wandie", "Wandis", "Waneta", "Wanids", "Wenda", "Wendeline", "Wendi", "Wendie", "Wendy", "Wendye", "Wenona", "Wenonah", "Whitney", "Wileen", "Wilhelmina", "Wilhelmine", "Wilie", "Willa", "Willabella", "Willamina", "Willetta", "Willette", "Willi", "Willie", "Willow", "Willy", "Willyt", "Wilma", "Wilmette", "Wilona", "Wilone", "Wilow", "Windy", "Wini", "Winifred", "Winna", "Winnah", "Winne", "Winni", "Winnie", "Winnifred", "Winny", "Winona", "Winonah", "Wren", "Wrennie", "Wylma", "Wynn", "Wynne", "Wynnie", "Wynny", "Xaviera", "Xena", "Xenia", "Xylia", "Xylina", "Yalonda", "Yasmeen", "Yasmin", "Yelena", "Yetta", "Yettie", "Yetty", "Yevette", "Ynes", "Ynez", "Yoko", "Yolanda", "Yolande", "Yolane", "Yolanthe", "Yoshi", "Yoshiko", "Yovonnda", "Ysabel", "Yvette", "Yvonne", "Zabrina", "Zahara", "Zandra", "Zaneta", "Zara", "Zarah", "Zaria", "Zarla", "Zea", "Zelda", "Zelma", "Zena", "Zenia", "Zia", "Zilvia", "Zita", "Zitella", "Zoe", "Zola", "Zonda", "Zondra", "Zonnya", "Zora", "Zorah", "Zorana", "Zorina", "Zorine", "Zsa Zsa", "Zsazsa", "Zulema", "Zuzana");
  5967. break;
  5968. }
  5969. $result .= $names[array_rand($names)] . ' ' . $surnames[array_rand($surnames)];
  5970. return ($result);
  5971. }
  5972. /**
  5973. * Returns current system version
  5974. *
  5975. * @return string
  5976. */
  5977. function zb_getLocalSystemVersion() {
  5978. $result = file_get_contents('RELEASE');
  5979. return ($result);
  5980. }
  5981. /**
  5982. * Returns remote release version
  5983. *
  5984. * @param string $branch
  5985. *
  5986. * @return string/bool
  5987. */
  5988. function zb_GetReleaseInfo($branch) {
  5989. $result = false;
  5990. $release_url = UbillingUpdateManager::URL_RELEASE_STABLE;
  5991. if ($branch == 'CURRENT') {
  5992. $release_url = UbillingUpdateManager::URL_RELEASE_CURRENT;
  5993. }
  5994. $ubVer = file_get_contents('RELEASE');
  5995. $agent = 'UbillingUpdMgr/' . trim($ubVer);
  5996. $remoteCallback = new OmaeUrl($release_url);
  5997. $remoteCallback->setUserAgent($agent);
  5998. $releaseInfo = $remoteCallback->response();
  5999. if ($remoteCallback->httpCode() == 200) {
  6000. if ($releaseInfo) {
  6001. $result = $releaseInfo;
  6002. }
  6003. }
  6004. return ($result);
  6005. }
  6006. /**
  6007. * Ajax backend for rendering WolfRecorder updates release info
  6008. *
  6009. * @param bool $version
  6010. * @param bool $branch
  6011. *
  6012. * @return string/bool
  6013. */
  6014. function zb_RenderUpdateInfo($version = '', $branch = 'STABLE') {
  6015. $result = '';
  6016. $latestRelease = $version;
  6017. if ($latestRelease) {
  6018. if ($branch == 'CURRENT') {
  6019. $result = __('Latest nightly Ubilling build is') . ': ' . $latestRelease;
  6020. } else {
  6021. $result = __('Latest stable Ubilling release is') . ': ' . $latestRelease;
  6022. }
  6023. } else {
  6024. $result = __('Error checking updates') . ' ' . $branch;
  6025. }
  6026. return ($result);
  6027. }
  6028. /**
  6029. * Returns avatar control form
  6030. *
  6031. * @param string $backUrl base64 encoded url
  6032. *
  6033. * @return string
  6034. */
  6035. function web_avatarControlForm($backUrl = '') {
  6036. global $ubillingConfig;
  6037. $myLogin = whoami();
  6038. $mail = gravatar_GetUserEmail($myLogin);
  6039. $serviceUrl = '';
  6040. $serviceName = '';
  6041. $avatarService = $ubillingConfig->getAlterParam('GRAVATAR_SERVICE');
  6042. switch ($avatarService) {
  6043. case 'gravatar':
  6044. $serviceUrl = 'https://gravatar.com/';
  6045. $serviceName = 'Gravatar';
  6046. break;
  6047. case 'libravatar':
  6048. $serviceUrl = 'https://libravatar.org/';
  6049. $serviceName = 'Libravatar';
  6050. break;
  6051. default:
  6052. $serviceUrl = 'https://libravatar.org/';
  6053. $serviceName = 'Libravatar';
  6054. break;
  6055. }
  6056. $cells = wf_TableCell(wf_tag('h1') . $myLogin . wf_tag('h1', true), '', '', 'align="center"');
  6057. $rows = wf_TableRow($cells);
  6058. $cells = wf_TableCell(gravatar_ShowAdminAvatar($myLogin, '256'), '', '', 'align="center"');
  6059. $rows .= wf_TableRow($cells);
  6060. $cells = wf_TableCell(wf_tag('h3') . __('Your email') . ': ' . $mail . wf_tag('h3', true), '', '', 'align="center"');
  6061. $rows .= wf_TableRow($cells);
  6062. $controlLink = wf_Link($serviceUrl, __('Change my avatar at') . ' ' . $serviceName, false, 'ubButton', 'target="_blank"');
  6063. $cells = wf_TableCell($controlLink, false, '', 'align="center"');
  6064. $rows .= wf_TableRow($cells);
  6065. if (cfr('ROOT')) {
  6066. $cacheFlushUrl = UBMessenger::URL_AVATAR_CONTROL . '&flushavacache=true';
  6067. $cancelUrl = UBMessenger::URL_AVATAR_CONTROL;
  6068. if (ubRouting::checkGet('back')) {
  6069. $cacheFlushUrl .= '&back=' . ubRouting::get('back');
  6070. $cancelUrl .= '&back=' . ubRouting::get('back');
  6071. }
  6072. $cacheFlushLink = wf_ConfirmDialog($cacheFlushUrl, wf_img('skins/icon_cleanup.png') . ' ' . __('Cache cleanup'), __('Cache cleanup'), 'ubButton', $cancelUrl, __('Are you serious'));
  6073. $cells = wf_TableCell($cacheFlushLink, false, '', 'align="center"');
  6074. $rows .= wf_TableRow($cells);
  6075. }
  6076. $result = wf_TableBody($rows, '100%', '0', 'glamour');
  6077. $result .= wf_CleanDiv();
  6078. if ($backUrl) {
  6079. $backUrl = base64_decode($backUrl);
  6080. $result .= wf_delimiter();
  6081. $result .= wf_BackLink($backUrl, __('Back'), false, 'ubButton');
  6082. }
  6083. return ($result);
  6084. }
  6085. /**
  6086. * Renders task bar elements quick search form
  6087. *
  6088. * @return string
  6089. */
  6090. function web_TaskBarQuickSearchForm() {
  6091. $result = '';
  6092. $result .= wf_tag('div', false, 'tbqsearchform');
  6093. $result .= wf_TextInput('tbquicksearch', ' ' . '', '', false, 20, '', '', 'tbquicksearch', 'placeholder="' . __('Quick search') . '...' . '"');
  6094. $result .= wf_tag('button', false, 'clear-btn', 'type="button" aria-label="Clear search"') . '&times;' . wf_tag('button', true);
  6095. $result .= wf_tag('div', true);
  6096. $result .= wf_tag('script');
  6097. $result .= "
  6098. document.getElementById('tbquicksearch').addEventListener('input', function () {
  6099. const searchValue = this.value.toLowerCase();
  6100. const tbElements = document.querySelectorAll('[id^=\"ubtbelcont_\"]');
  6101. const statusContainer = document.getElementById('ubtbqsstatus');
  6102. let visibleCount = 0;
  6103. tbElements.forEach(tbElement => {
  6104. const idText = tbElement.id.toLowerCase();
  6105. if (searchValue === '' || idText.includes(searchValue)) {
  6106. tbElement.classList.remove('hiddentbelem');
  6107. tbElement.style.display = 'block';
  6108. requestAnimationFrame(() => tbElement.style.opacity = '1');
  6109. visibleCount++;
  6110. } else {
  6111. tbElement.classList.add('hiddentbelem');
  6112. setTimeout(() => {
  6113. if (tbElement.classList.contains('hiddentbelem')) {
  6114. tbElement.style.display = 'none';
  6115. }
  6116. }, 300);
  6117. }
  6118. });
  6119. //no elements found
  6120. if (visibleCount === 0) {
  6121. statusContainer.textContent = '" . __('Nothing found') . "';
  6122. } else {
  6123. statusContainer.textContent = '';
  6124. }
  6125. });
  6126. document.addEventListener('DOMContentLoaded', () => {
  6127. const searchInput = document.getElementById('tbquicksearch');
  6128. const clearButton = document.querySelector('.clear-btn');
  6129. searchInput.addEventListener('input', () => {
  6130. if (searchInput.value.trim() !== '') {
  6131. clearButton.style.display = 'flex';
  6132. } else {
  6133. clearButton.style.display = 'none';
  6134. }
  6135. });
  6136. clearButton.addEventListener('click', () => {
  6137. searchInput.value = '';
  6138. clearButton.style.display = 'none';
  6139. searchInput.dispatchEvent(new Event('input'));
  6140. searchInput.focus();
  6141. });
  6142. });
  6143. ";
  6144. $result .= wf_tag('script', true);
  6145. $result .= wf_CleanDiv();
  6146. return ($result);
  6147. }
  6148. /**
  6149. * Flushes cached avatars for all users
  6150. *
  6151. * @return void
  6152. */
  6153. function zb_avatarFlushCache() {
  6154. $avaPath = 'content/avatars/';
  6155. $allAvatars = rcms_scandir($avaPath, '*.jpg');
  6156. if (!empty($allAvatars)) {
  6157. foreach ($allAvatars as $io => $each) {
  6158. unlink($avaPath . $each);
  6159. }
  6160. }
  6161. log_register('AVACONTROL CACHE FLUSH');
  6162. }
  6163. /**
  6164. * Renders the PonSignal colored based on the signal strength.
  6165. *
  6166. * @param float $signal The signal strength value.
  6167. *
  6168. * @return string
  6169. */
  6170. function zb_PonSignalColorize($signal) {
  6171. $result = '';
  6172. if (($signal > 0) or ($signal < -27)) {
  6173. $sigColor = PONizer::COLOR_BAD;
  6174. $sigLabel = 'Bad signal';
  6175. } elseif ($signal > -27 and $signal < -25) {
  6176. $sigColor = PONizer::COLOR_AVG;
  6177. $sigLabel = 'Mediocre signal';
  6178. } else {
  6179. $sigColor = PONizer::COLOR_OK;
  6180. $sigLabel = 'Normal';
  6181. }
  6182. if ($signal == PONizer::NO_SIGNAL) {
  6183. $signal = __('No');
  6184. $sigColor = PONizer::COLOR_NOSIG;
  6185. $sigLabel = 'No signal';
  6186. }
  6187. $result .= wf_tag('font', false, '', 'color="' . $sigColor . '" title="' . __($sigLabel) . '"');
  6188. $result .= $signal;
  6189. $result .= wf_tag('font', true);
  6190. return ($result);
  6191. }
  6192. /**
  6193. * Returns assigned ONU signal/dereg reason
  6194. *
  6195. * @param string $login
  6196. * @param bool $colored
  6197. * @param bool $label
  6198. * @param bool $onuLink
  6199. *
  6200. * @return string
  6201. */
  6202. function zb_getPonSignalData($login = '', $colored = false, $label = false, $onuLink = false) {
  6203. global $ubillingConfig;
  6204. $result = '';
  6205. if (!empty($login)) {
  6206. if ($ubillingConfig->getAlterParam('PON_ENABLED')) {
  6207. if ($ubillingConfig->getAlterParam('PON_ENABLED')) {
  6208. $signal = 'ETAOIN SHRDLU';
  6209. $deregReason = '';
  6210. $ponizerDb = new NyanORM(PONizer::TABLE_ONUS);
  6211. $ponizerDb->where('login', '=', $login);
  6212. $onuData = $ponizerDb->getAll();
  6213. if (empty($onuData)) {
  6214. //no primary assign found?
  6215. $ponizerOnuExtDb = new NyanORM(PONizer::TABLE_ONUEXTUSERS);
  6216. $ponizerOnuExtDb->where('login', '=', $login);
  6217. $assignedOnuExt = $ponizerOnuExtDb->getAll();
  6218. if (!empty($assignedOnuExt)) {
  6219. $ponizerDb->where('id', '=', $assignedOnuExt[0]['onuid']);
  6220. $onuData = $ponizerDb->getAll();
  6221. }
  6222. }
  6223. if (!empty($onuData)) {
  6224. $onuData = $onuData[0];
  6225. $onuId = $onuData['id'];
  6226. $oltId = $onuData['oltid'];
  6227. $oltAttractor = new OLTAttractor($oltId);
  6228. $allSignals = $oltAttractor->getSignalsAll();
  6229. //lookup latest ONU signal
  6230. $signalLookup = $oltAttractor->lookupOnuIdxValue($onuData, $allSignals);
  6231. if ($signalLookup != false) {
  6232. $signal = $signalLookup;
  6233. }
  6234. if ($onuId) {
  6235. //is ONU signal found in signals cache?
  6236. $signal = ($signal == 'ETAOIN SHRDLU') ? PONizer::NO_SIGNAL : $signal;
  6237. if ($colored) {
  6238. $signalLabel = zb_PonSignalColorize($signal);
  6239. } else {
  6240. $signalLabel = $signal;
  6241. }
  6242. //ONU is offline?
  6243. if ($signal == PONizer::NO_SIGNAL) {
  6244. //lookup last dereg reason
  6245. $allDeregReasons = $oltAttractor->getDeregsAll();
  6246. $deregLookup = $oltAttractor->lookupOnuIdxValue($onuData, $allDeregReasons);
  6247. if ($deregLookup != false) {
  6248. $deregReason = $deregLookup;
  6249. }
  6250. if (!empty($deregReason)) {
  6251. if ($colored) {
  6252. $signalLabel .= ' - ' . $deregReason;
  6253. } else {
  6254. $signalLabel .= ' - ' . strip_tags($deregReason);
  6255. }
  6256. }
  6257. }
  6258. if ($onuLink) {
  6259. $signalLabel = wf_Link(PONizer::URL_ONU . $onuId, $signalLabel);
  6260. }
  6261. if ($label) {
  6262. $result .= __('ONU Signal') . ': ' . $signalLabel;
  6263. } else {
  6264. $result .= $signalLabel;
  6265. }
  6266. }
  6267. } else {
  6268. $result .= __('No ONU assigned');
  6269. }
  6270. }
  6271. }
  6272. }
  6273. return ($result);
  6274. }
  6275. /**
  6276. * Trims the content of a log file if it exceeds a specified size.
  6277. *
  6278. * This function checks if the specified log file exists and if its size exceeds
  6279. * the given maximum size. If the file size exceeds the limit, it trims the file
  6280. * content by removing lines from the beginning until the file size is within the limit.
  6281. *
  6282. * @param string $fileName The path to the text log file.
  6283. * @param int $size The maximum allowed size of the log file in megabytes (MB).
  6284. *
  6285. * @return void
  6286. */
  6287. function zb_TrimTextLog($fileName, $size) {
  6288. if (file_exists($fileName)) {
  6289. $maxSize = $size * 1024 * 1024; // in mb
  6290. $fileSize = filesize($fileName);
  6291. if ($fileSize >= $maxSize) {
  6292. $fileContent = file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
  6293. if (!empty($fileContent)) {
  6294. $fileContent = array_reverse($fileContent);
  6295. $seekSize = 0;
  6296. foreach ($fileContent as $io => $each) {
  6297. $seekSize += strlen($each);
  6298. if ($seekSize >= $maxSize) {
  6299. unset($fileContent[$io]);
  6300. }
  6301. }
  6302. $fileContent = array_reverse($fileContent);
  6303. file_put_contents($fileName, implode(PHP_EOL, $fileContent) . PHP_EOL);
  6304. }
  6305. }
  6306. }
  6307. }