| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535 |
- <?php
- /**
- * Builder data handling class that deals
- * with all database operations.
- *
- * @since 1.0
- */
- final class FLBuilderModel {
- /**
- * An array that contains the sizes for columns
- * in each row layout.
- *
- * @since 1.0
- * @var array $row_layouts
- */
- static public $row_layouts = array(
- '1-col' => array( 100 ),
- '2-cols' => array( 50, 50 ),
- '3-cols' => array( 33.33, 33.33, 33.33 ),
- '4-cols' => array( 25, 25, 25, 25 ),
- '5-cols' => array( 20, 20, 20, 20, 20 ),
- '6-cols' => array( 16.65, 16.65, 16.65, 16.65, 16.65, 16.65 ),
- 'left-sidebar' => array( 33.33, 66.66 ),
- 'right-sidebar' => array( 66.66, 33.33 ),
- 'left-right-sidebar' => array( 25, 50, 25 ),
- );
- /**
- * An array that contains data for each registered settings form.
- *
- * @since 1.0
- * @var array $settings_forms
- */
- static public $settings_forms = array();
- /**
- * An array used to cache default values for settings forms.
- *
- * @since 1.0
- * @var array $settings_form_defaults
- */
- static public $settings_form_defaults = array();
- /**
- * An array that instances for each registered module.
- *
- * @since 1.0
- * @var array $modules
- */
- static public $modules = array();
- /**
- * An array of module aliases with their own names,
- * categories and default settings.
- *
- * @since 1.10
- * @var array $module_aliases
- */
- static public $module_aliases = array();
- /**
- * Whether the builder is active or not.
- *
- * @since 1.10
- * @access private
- * @var bool $active
- */
- static private $active = null;
- /**
- * Cached global settings.
- *
- * @access private
- * @var array $global_settings
- */
- static private $global_settings;
- /**
- * The last node id that was generated by the builder.
- * This is saved to ensure the next node id is unique.
- *
- * @since 1.0
- * @access private
- * @var string $last_generated_node_id
- */
- static private $last_generated_node_id = null;
- /**
- * Cached post data from either the $_POST array
- * or from the fl_builder_data post variable.
- *
- * @since 1.0
- * @access private
- * @var array $post_data
- */
- static private $post_data = null;
- /**
- * An array of post IDs the builder will be forced to use instead
- * of a post ID set in the internal $post_data array or the global
- * $post->ID when calling the FLBuilderModel::get_post_id method.
- *
- * The first post ID in the array is always returned for the
- * FLBuilderModel::get_post_id method. To get a previously set
- * post ID, first call the FLBuilderModel::reset_post_id method.
- *
- * @since 1.10
- * @access private
- * @var array $post_id
- */
- static private $post_id = array();
- /**
- * An array of cached published layout data by post_id.
- *
- * @since 1.0
- * @access private
- * @var array $published_layout_data
- */
- static private $published_layout_data = array();
- /**
- * An array of cached draft layout data by post_id.
- *
- * @since 1.0
- * @access private
- * @var array $draft_layout_data
- */
- static private $draft_layout_data = array();
- /**
- * An array of paths to template data files.
- *
- * @since 1.8
- * @access private
- * @var array $templates
- */
- static private $templates = array();
- /**
- * An array of cached template data that has been
- * loaded from .dat files.
- *
- * @since 1.10
- * @access private
- * @var array $template_data
- */
- static private $template_data = null;
- /**
- * An array of cached post IDs for node templates.
- *
- * @since 1.7.6
- * @access private
- * @var array $node_template_post_ids
- */
- static private $node_template_post_ids = array();
- /**
- * An array of cached types for user and node templates.
- *
- * @since 1.7.9
- * @access private
- * @var array $node_template_types
- */
- static private $node_template_types = array();
- /**
- * Initialize hooks.
- *
- * @since 1.8
- * @return void
- */
- static public function init() {
- /* Admin AJAX */
- add_action( 'wp_ajax_fl_builder_disable', __CLASS__ . '::disable' );
- add_action( 'wp_ajax_fl_builder_duplicate_wpml_layout', __CLASS__ . '::duplicate_wpml_layout' );
- /* Actions */
- add_action( 'init', __CLASS__ . '::load_settings', 1 );
- add_action( 'init', __CLASS__ . '::load_modules', 2 );
- add_action( 'before_delete_post', __CLASS__ . '::delete_post' );
- add_action( 'save_post', __CLASS__ . '::save_revision' );
- add_action( 'save_post', __CLASS__ . '::set_node_template_default_type', 10, 3 );
- add_action( 'wp_restore_post_revision', __CLASS__ . '::restore_revision', 10, 2 );
- /* Filters */
- add_filter( 'heartbeat_received', __CLASS__ . '::lock_post', 10, 2 );
- add_filter( 'fl_builder_register_settings_form', __CLASS__ . '::filter_row_settings_for_resize', 10, 2 );
- /* Core Templates */
- self::register_core_templates();
- }
- /**
- * Returns a builder edit URL for a post.
- *
- * @since 1.0
- * @param int $post_id The post id to get an edit url for.
- * @return string
- */
- static public function get_edit_url( $post_id = false ) {
- if ( false === $post_id ) {
- global $post;
- } else {
- $post = get_post( $post_id );
- }
- preg_match( '/(https?)/', get_bloginfo( 'url' ), $matches );
- $scheme = ( isset( $matches[1] ) ) ? $matches[1] : false;
- return set_url_scheme( add_query_arg( 'fl_builder', '', get_permalink( $post->ID ) ), $scheme );
- }
- /**
- * Returns the URL to upgrade the builder to the premium version.
- * Can be overridden by theme developers to use their affiliate
- * link using the fl_builder_upgrade_url filter.
- *
- * @since 1.0
- * @param array $params An array of key/value params to add to the query string.
- * @return string
- */
- static public function get_upgrade_url( $params = array() ) {
- /**
- * Use this filter to modify the upgrade URL in Beaver Builder Lite.
- * This can be used to add an affiliate ID.
- * @see fl_builder_upgrade_url
- * @link https://kb.wpbeaverbuilder.com/article/117-plugin-filter-reference
- */
- return apply_filters( 'fl_builder_upgrade_url', self::get_store_url( '', $params ) );
- }
- /**
- * Returns a URL that points to the Beaver Builder store.
- *
- * @since 1.8.6
- * @param string $path A URL path to append to the store URL.
- * @param array $params An array of key/value params to add to the query string.
- * @return string
- */
- static public function get_store_url( $path = '', $params = array() ) {
- $url = trailingslashit( FL_BUILDER_STORE_URL . $path ) . '?' . http_build_query( $params, '', '&' );
- return apply_filters( 'fl_builder_store_url', $url, $path );
- }
- /**
- * Returns an array of post data from either $_POST['fl_builder_data']
- * or $_POST if that is not set.
- *
- * @since 1.0
- * @return array
- */
- static public function get_post_data() {
- if ( ! self::$post_data ) {
- self::$post_data = array();
- if ( isset( $_POST['fl_builder_data'] ) ) {
- // Decode settings if our ModSecurity fix is enabled.
- if ( isset( $_POST['fl_builder_data']['settings'] ) ) {
- $_POST['fl_builder_data']['settings'] = FLBuilderUtils::modsec_fix_decode( $_POST['fl_builder_data']['settings'] );
- }
- if ( isset( $_POST['fl_builder_data']['node_settings'] ) ) {
- $_POST['fl_builder_data']['node_settings'] = FLBuilderUtils::modsec_fix_decode( $_POST['fl_builder_data']['node_settings'] );
- }
- $data = FLBuilderUtils::json_decode_deep( wp_unslash( $_POST['fl_builder_data'] ) );
- foreach ( $data as $key => $val ) {
- self::$post_data[ $key ] = $val;
- }
- } elseif ( isset( $_POST ) ) {
- foreach ( $_POST as $key => $val ) {
- self::$post_data[ $key ] = $val;
- }
- }
- }
- return self::$post_data;
- }
- /**
- * Update a value in the $post_data array.
- *
- * @since 1.0
- * @param string $key The post data key.
- * @param mixed $value The value to update.
- * @return void
- */
- static public function update_post_data( $key, $value ) {
- $post_data = self::get_post_data();
- $post_data[ $key ] = $value;
- self::$post_data = $post_data;
- }
- /**
- * Return an array of post types that the builder
- * is enabled to work with.
- *
- * @since 1.0
- * @return array
- */
- static public function get_post_types() {
- $value = self::get_admin_settings_option( '_fl_builder_post_types', true );
- if ( ! $value ) {
- $value = array( 'page', 'fl-builder-template' );
- } else {
- $value[] = 'fl-builder-template';
- }
- /**
- * Use this filter to modify the post types that the builder works with.
- * @see fl_builder_post_types
- * @link https://kb.wpbeaverbuilder.com/article/117-plugin-filter-reference
- */
- return apply_filters( 'fl_builder_post_types', $value );
- }
- /**
- * Return an array of post ids that should have their
- * builder assets loaded globally.
- *
- * @since 1.0
- * @return array
- */
- static public function get_global_posts() {
- /**
- * Use this filter to specify a post or posts whose CSS and JavaScript assets should be loaded globally.
- * @link https://kb.wpbeaverbuilder.com/article/117-plugin-filter-reference
- * @see fl_builder_global_posts
- * @since 1.0
- */
- return apply_filters( 'fl_builder_global_posts', array() );
- }
- /**
- * Adds the given post ID to the beginning of the internal $post_id
- * array so the builder will be forced to use that instead of
- * a post ID set in the internal $post_data array or the global $post->ID.
- *
- * @since 1.10
- * @param int $post_id
- * @return void
- */
- static public function set_post_id( $post_id ) {
- array_unshift( self::$post_id, $post_id );
- }
- /**
- * Removes the first item from the internal $post_id array so the
- * last set post ID is used. If the internal $post_id array is
- * empty, a post ID set in the internal $post_data array or the global
- * $post->ID will be used when calling FLBuilderModel::get_post_id.
- *
- * @since 1.10
- * @return void
- */
- static public function reset_post_id() {
- array_shift( self::$post_id );
- }
- /**
- * Returns the post id for the current post that
- * is being displayed or worked on.
- *
- * @since 1.0
- * @param bool $force_globals Force the use of WP globals instead of checking our internal post ID.
- * @return int|bool The post id or false.
- */
- static public function get_post_id( $force_globals = false ) {
- // Check our internal post IDs first if we're not forced to use WP globals.
- if ( ! $force_globals ) {
- $post_data = self::get_post_data();
- if ( ! empty( self::$post_id ) ) {
- // Get a post ID from the internal $post_id array if not empty.
- return self::$post_id[0];
- } elseif ( isset( $post_data['post_id'] ) ) {
- // Get a post ID from an AJAX request.
- return $post_data['post_id'];
- }
- }
- // Check WP globals.
- global $wp_the_query;
- global $post;
- if ( in_the_loop() && is_main_query() && isset( $wp_the_query->post ) ) {
- // Get a post ID from the main query.
- return $wp_the_query->post->ID;
- } elseif ( isset( $post ) ) {
- // Get a post ID in a query outside of the main loop.
- return $post->ID;
- }
- // No post ID found.
- return false;
- }
- /**
- * Returns the post object for the current post that
- * is being worked on.
- *
- * @since 1.6.3
- * @return object
- */
- static public function get_post() {
- return get_post( self::get_post_id() );
- }
- /**
- * Checks to see if the site has SSL enabled or not.
- *
- * @since 1.0
- * @return bool
- */
- static public function is_ssl() {
- if ( is_ssl() ) {
- return true;
- } elseif ( 0 === stripos( get_option( 'siteurl' ), 'https://' ) ) {
- return true;
- } elseif ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' == $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
- return true;
- }
- return false;
- }
- /**
- * Checks to see if the builder can be enabled for
- * the current post in the main query.
- *
- * @since 1.0
- * @return bool
- */
- static public function is_post_editable() {
- global $wp_the_query;
- $editable = false;
- if ( is_singular() && isset( $wp_the_query->post ) ) {
- $post = $wp_the_query->post;
- $post_types = self::get_post_types();
- $user_can = current_user_can( 'edit_post', $post->ID );
- $user_access = FLBuilderUserAccess::current_user_can( 'builder_access' );
- if ( in_array( $post->post_type, $post_types ) && $user_can && $user_access ) {
- $editable = true;
- }
- }
- return (bool) apply_filters( 'fl_builder_is_post_editable', $editable );
- }
- /**
- * Called by the heartbeat API. Lock the current post
- * so only the current user can edit it.
- *
- * @since 1.0
- * @return void
- */
- static public function lock_post( $response, $data ) {
- if ( isset( $data['fl_builder_post_lock'] ) ) {
- require_once ABSPATH . 'wp-admin/includes/post.php';
- wp_set_post_lock( $data['fl_builder_post_lock']['post_id'] );
- }
- }
- /**
- * Checks to see if the builder layout is enabled
- * for the current post.
- *
- * @since 1.0
- * @param int $post_id A post ID to check otherwise, self::get_post_id will be used.
- * @return bool
- */
- static public function is_builder_enabled( $post_id = null ) {
- global $wp_the_query;
- // If in iframe preview return true as the post might not be a draft yet.
- if ( self::is_builder_draft_preview() ) {
- return true;
- }
- $query_id = ( isset( $wp_the_query->post->ID ) ) ? $wp_the_query->post->ID : false;
- $post_id = $post_id ? $post_id : self::get_post_id();
- if ( ! is_admin() && post_password_required( $post_id ) ) {
- return false;
- } elseif ( self::is_builder_active() && $query_id === $post_id ) {
- return true;
- } else {
- $post_types = self::get_post_types();
- $post = get_post( $post_id );
- if ( $post && in_array( $post->post_type, $post_types ) ) {
- return get_post_meta( $post->ID, '_fl_builder_enabled', true );
- }
- }
- return false;
- }
- /**
- * Checks to see if the builder UI is active for
- * the current post in the main query.
- *
- * @since 1.0
- * @return bool
- */
- static public function is_builder_active() {
- global $wp_the_query;
- global $post;
- $query_id = ( isset( $wp_the_query->post->ID ) ) ? $wp_the_query->post->ID : false;
- $post_id = ( isset( $post->ID ) ) ? $post->ID : false;
- if ( null !== self::$active ) {
- return self::$active;
- } elseif ( ! is_admin() && is_singular() && $query_id != $post_id ) {
- self::$active = false;
- } elseif ( is_customize_preview() ) {
- self::$active = false;
- } elseif ( self::is_post_editable() && ! is_admin() && ! post_password_required() ) {
- $post_data = self::get_post_data();
- self::$active = isset( $_GET['fl_builder'] ) || isset( $post_data['fl_builder'] );
- }
- return self::$active;
- }
- /**
- * Returns if this is a draft layout preview or not.
- *
- * @since 2.1
- * @return bool
- */
- static public function is_builder_draft_preview() {
- return is_user_logged_in() && isset( $_GET['fl_builder_preview'] );
- }
- /**
- * Checks to see if this is the first time
- * a user has launched the builder.
- *
- * @since 1.4.9
- * @return bool
- */
- static public function is_new_user() {
- if ( self::is_builder_active() ) {
- $current_user = wp_get_current_user();
- $launched = get_user_meta( $current_user->ID, '_fl_builder_launched', true );
- if ( empty( $launched ) ) {
- update_user_meta( $current_user->ID, '_fl_builder_launched', 1 );
- return true;
- }
- }
- return false;
- }
- /**
- * Gets the status to use for working with nodes in
- * the database. Returns draft if the builder is active,
- * otherwise it returns published.
- *
- * @since 1.0
- * @return string
- */
- static public function get_node_status() {
- $status = self::is_builder_active() ? 'draft' : 'published';
- return apply_filters( 'fl_builder_node_status', $status );
- }
- /**
- * Enable the builder layout for the current post.
- *
- * @since 1.0
- * @return void
- */
- static public function enable() {
- update_post_meta( self::get_post_id(), '_fl_builder_enabled', true );
- }
- /**
- * Disable the builder layout for the current post.
- *
- * @since 1.0
- * @return void
- */
- static public function disable() {
- update_post_meta( self::get_post_id(), '_fl_builder_enabled', false );
- }
- /**
- * Enable the builder editor for the main post in the query.
- *
- * @since 1.0
- * @return void
- */
- static public function enable_editing() {
- global $wp_the_query;
- if ( self::is_post_editable() && is_object( $wp_the_query->post ) ) {
- $post = $wp_the_query->post;
- $published = self::get_layout_data( 'published' );
- $draft = self::get_layout_data( 'draft' );
- $content = apply_filters( 'fl_builder_migrated_post_content', $post->post_content );
- // Migrate existing post content to the builder?
- if ( empty( $published ) && empty( $draft ) && ! empty( $content ) ) {
- $row = self::add_row();
- $cols = self::get_nodes( 'column' );
- $col = array_shift( $cols );
- $settings = self::get_module_defaults( 'rich-text' );
- $settings->text = $content;
- self::add_module( 'rich-text', $settings, $col->node );
- } elseif ( empty( $draft ) ) {
- self::update_layout_data( $published, 'draft', $post->ID );
- self::update_layout_settings( self::get_layout_settings( 'published' ), 'draft', $post->ID );
- }
- // Delete old draft asset cache.
- self::delete_asset_cache();
- // Lock the post.
- require_once ABSPATH . 'wp-admin/includes/post.php';
- wp_set_post_lock( $post->ID );
- // Allow devs to hook into when editing is enabled.
- do_action( 'fl_builder_editing_enabled' );
- }
- }
- /**
- * Returns an array of paths for the upload directory
- * of the current site.
- *
- * @since 1.0
- * @return array
- */
- static public function get_upload_dir() {
- $wp_info = wp_upload_dir( null, false );
- $dir_name = basename( FL_BUILDER_DIR );
- // We use bb-plugin for the lite version as well.
- if ( 'beaver-builder-lite-version' == $dir_name ) {
- $dir_name = 'bb-plugin';
- }
- // SSL workaround.
- if ( self::is_ssl() ) {
- $wp_info['baseurl'] = str_ireplace( 'http://', 'https://', $wp_info['baseurl'] );
- }
- // Build the paths.
- $dir_info = array(
- 'path' => $wp_info['basedir'] . '/' . $dir_name . '/',
- 'url' => $wp_info['baseurl'] . '/' . $dir_name . '/',
- );
- // Create the upload dir if it doesn't exist.
- if ( ! fl_builder_filesystem()->file_exists( $dir_info['path'] ) ) {
- // Create the directory.
- fl_builder_filesystem()->mkdir( $dir_info['path'] );
- // Add an index file for security.
- fl_builder_filesystem()->file_put_contents( $dir_info['path'] . 'index.html', '' );
- }
- /**
- * Use this filter to modify the upload directory path and URL that the builder uses to store things like the cache and custom icons.
- * @see fl_builder_get_upload_dir
- * @link https://kb.wpbeaverbuilder.com/article/117-plugin-filter-reference
- */
- return apply_filters( 'fl_builder_get_upload_dir', $dir_info );
- }
- /**
- * Returns an array of paths for the cache directory
- * of the current site.
- *
- * @since 1.0
- * @param string $name The name of the cache directory to get paths for.
- * @return array
- */
- static public function get_cache_dir( $name = 'cache' ) {
- $upload_info = self::get_upload_dir();
- $allowed = array( 'cache', 'icons' );
- // Make sure the dir name is allowed.
- if ( ! in_array( $name, $allowed ) ) {
- return false;
- }
- // Build the paths.
- $dir_info = array(
- 'path' => $upload_info['path'] . $name . '/',
- 'url' => $upload_info['url'] . $name . '/',
- );
- // Create the cache dir if it doesn't exist.
- if ( ! fl_builder_filesystem()->file_exists( $dir_info['path'] ) ) {
- // Create the directory.
- fl_builder_filesystem()->mkdir( $dir_info['path'] );
- // Add an index file for security.
- fl_builder_filesystem()->file_put_contents( $dir_info['path'] . 'index.html', '' );
- }
- /**
- * Use this filter to modify the cache directory path and URL that the builder uses to store cached images, JavaScript, and CSS files.
- * @link https://kb.wpbeaverbuilder.com/article/117-plugin-filter-reference
- * @see fl_builder_get_cache_dir
- */
- return apply_filters( 'fl_builder_get_cache_dir', $dir_info );
- }
- /**
- * Returns the version number to be applied to the query string
- * of a CSS or JS asset. If the builder is active a random hash
- * is returned to prevent caching, otherwise a hash of the post
- * update time is returned.
- *
- * @since 1.0
- * @return string
- */
- static public function get_asset_version() {
- $post_id = self::get_post_id();
- $active = self::is_builder_active();
- $preview = self::is_builder_draft_preview();
- if ( $active || $preview ) {
- return md5( uniqid() );
- } else {
- return md5( get_post_modified_time( 'U', false, $post_id ) );
- }
- }
- /**
- * Returns an array of paths for the CSS and JS assets
- * of the current post.
- *
- * @since 1.0
- * @return array
- */
- static public function get_asset_info() {
- $post_data = self::get_post_data();
- $post_id = self::get_post_id();
- $cache_dir = self::get_cache_dir();
- $active = self::is_builder_active();
- $preview = self::is_builder_draft_preview();
- if ( isset( $post_data['node_preview'] ) ) {
- $suffix = '-layout-preview';
- } elseif ( $active || $preview ) {
- $suffix = '-layout-draft';
- } else {
- $suffix = '-layout';
- }
- $info = array(
- 'css' => $cache_dir['path'] . $post_id . $suffix . '.css',
- 'css_url' => $cache_dir['url'] . $post_id . $suffix . '.css',
- 'css_partial' => $cache_dir['path'] . $post_id . $suffix . '-partial.css',
- 'css_partial_url' => $cache_dir['url'] . $post_id . $suffix . '-partial.css',
- 'js' => $cache_dir['path'] . $post_id . $suffix . '.js',
- 'js_url' => $cache_dir['url'] . $post_id . $suffix . '.js',
- 'js_partial' => $cache_dir['path'] . $post_id . $suffix . '-partial.js',
- 'js_partial_url' => $cache_dir['url'] . $post_id . $suffix . '-partial.js',
- );
- return $info;
- }
- /**
- * Deletes either the preview, draft or live CSS and/or JS asset cache
- * for the current post based on the data returned from get_asset_info.
- * Both the CSS and JS asset cache will be delete if a type is not specified.
- *
- * @since 1.0
- * @param string $type The type of cache to delete. Either css or js.
- * @return void
- */
- static public function delete_asset_cache( $type = false ) {
- $info = self::get_asset_info();
- $types = $type ? array( $type ) : array( 'css', 'css_partial', 'js', 'js_partial' );
- foreach ( $types as $type ) {
- if ( isset( $info[ $type ] ) && fl_builder_filesystem()->file_exists( $info[ $type ] ) ) {
- fl_builder_filesystem()->unlink( $info[ $type ] );
- }
- }
- }
- /**
- * Deletes preview, draft and live CSS/JS asset cache for the current
- * post. If a post ID is supplied, the asset cache will be deleted for
- * that post instead.
- *
- * @since 1.0
- * @param int $post_id
- * @return void
- */
- static public function delete_all_asset_cache( $post_id = false ) {
- $post_id = $post_id ? $post_id : self::get_post_id();
- $cache_dir = self::get_cache_dir();
- if ( $post_id ) {
- $paths = array(
- $cache_dir['path'] . $post_id . '-layout.css',
- $cache_dir['path'] . $post_id . '-layout-draft.css',
- $cache_dir['path'] . $post_id . '-layout-preview.css',
- $cache_dir['path'] . $post_id . '-layout-partial.css',
- $cache_dir['path'] . $post_id . '-layout-draft-partial.css',
- $cache_dir['path'] . $post_id . '-layout-preview-partial.css',
- $cache_dir['path'] . $post_id . '-layout.js',
- $cache_dir['path'] . $post_id . '-layout-draft.js',
- $cache_dir['path'] . $post_id . '-layout-preview.js',
- $cache_dir['path'] . $post_id . '-layout-partial.js',
- $cache_dir['path'] . $post_id . '-layout-draft-partial.js',
- $cache_dir['path'] . $post_id . '-layout-preview-partial.js',
- );
- foreach ( $paths as $path ) {
- if ( fl_builder_filesystem()->file_exists( $path ) ) {
- fl_builder_filesystem()->unlink( $path );
- }
- }
- }
- }
- /**
- * Deletes the asset cache for all posts that contain the node
- * template with the supplied post ID.
- *
- * @since 1.6.3
- * @param int $post_id
- * @return void
- */
- static public function delete_node_template_asset_cache( $post_id = false ) {
- $posts = self::get_posts_with_global_node_template( $post_id );
- if ( ! empty( $posts ) ) {
- foreach ( $posts as $post ) {
- self::delete_all_asset_cache( $post->ID );
- }
- }
- }
- /**
- * Deletes preview, draft and live CSS/JS asset cache for all posts.
- *
- * @since 1.6.3
- * @return void
- */
- static public function delete_asset_cache_for_all_posts() {
- $cache_dir = self::get_cache_dir();
- $css = glob( $cache_dir['path'] . '*.css' );
- $js = glob( $cache_dir['path'] . '*.js' );
- if ( is_array( $css ) ) {
- array_map( array( fl_builder_filesystem(), 'unlink' ), $css );
- }
- if ( is_array( $js ) ) {
- array_map( array( fl_builder_filesystem(), 'unlink' ), $js );
- }
- }
- /**
- * Generates a unique id for a builder node such as a
- * row, column or module.
- *
- * @since 1.0
- * @return string
- */
- static public function generate_node_id() {
- $node_id = uniqid();
- if ( $node_id == self::$last_generated_node_id ) {
- return self::generate_node_id();
- }
- self::$last_generated_node_id = $node_id;
- return $node_id;
- }
- /**
- * Generates new node ids for an array of nodes.
- *
- * @since 1.0
- * @param array $data An array of node data.
- * @return array
- */
- static public function generate_new_node_ids( $data ) {
- $map = array();
- $nodes = array();
- // Map the new node ids to the old.
- foreach ( $data as $node_id => $node ) {
- $map[ $node_id ] = self::generate_node_id();
- }
- // Replace the old node ids.
- foreach ( $data as $node_id => $node ) {
- $nodes[ $map[ $node_id ] ] = $node;
- $nodes[ $map[ $node_id ] ]->node = $map[ $node_id ];
- if ( ! empty( $node->parent ) && isset( $map[ $node->parent ] ) ) {
- $nodes[ $map[ $node_id ] ]->parent = $map[ $node->parent ];
- }
- }
- return $nodes;
- }
- /**
- * Returns a single node.
- *
- * @since 1.0
- * @param string|object $node_id Either a node id or node object.
- * @param string $status The node status. Either draft or published.
- * @return object
- */
- static public function get_node( $node_id = null, $status = null ) {
- if ( is_object( $node_id ) ) {
- $node = $node_id;
- } else {
- $data = self::get_layout_data( $status );
- $node = isset( $data[ $node_id ] ) ? $data[ $node_id ] : null;
- }
- if ( $node && ! empty( $node->settings ) ) {
- $node->settings = self::get_node_settings( $node );
- }
- return $node;
- }
- /**
- * Returns an array of nodes.
- *
- * @since 1.0
- * @param string $type The type of nodes to return.
- * @param string|object $parent_id Either the parent node id or parent node object.
- * @param string $status The node status. Either draft or published.
- * @return array
- */
- static public function get_nodes( $type = null, $parent_id = null, $status = null ) {
- $parent = is_object( $parent_id ) ? $parent_id : self::get_node( $parent_id );
- $nodes = array();
- // Get the layout data.
- if ( ! $parent ) {
- $data = self::get_layout_data( $status );
- } else {
- $data = self::get_child_nodes( $parent, $status );
- }
- // Return all nodes?
- if ( ! $type ) {
- $nodes = $data;
- } else {
- foreach ( $data as $node_id => $node ) {
- if ( $node->type == $type ) {
- $nodes[ $node_id ] = $node;
- }
- }
- }
- // Sort the nodes by position.
- uasort( $nodes, array( 'FLBuilderModel', 'order_nodes' ) );
- // Merge default settings.
- foreach ( $nodes as $node_id => $node ) {
- if ( ! empty( $node->settings ) ) {
- $nodes[ $node_id ]->settings = self::get_node_settings( $nodes[ $node_id ] );
- }
- }
- // Return the nodes.
- return $nodes;
- }
- /**
- * Returns the direct parent object for a single node.
- *
- * @since 1.9
- * @param string|object $node_id Either a node id or node object.
- * @param string $status The node status. Either draft or published.
- * @return object
- */
- static public function get_node_parent( $node_id = null, $status = null ) {
- $parent = null;
- if ( is_object( $node_id ) ) {
- $node = $node_id;
- } else {
- $node = self::get_node( $node_id, $status );
- }
- if ( $node ) {
- $template_post_id = self::is_node_global( $node );
- $post_id = $template_post_id ? $template_post_id : self::get_post_id();
- $data = self::get_layout_data( $status, $post_id );
- if ( isset( $data[ $node->parent ] ) ) {
- return $data[ $node->parent ];
- }
- }
- return $parent;
- }
- /**
- * Returns a node's parent node of the specified type.
- *
- * @since 1.8.3
- * @param string|object $node The node ID. Can also be a node object.
- * @param string $type The type of parent to return. Either "column", "column-group" or "row".
- * @return object The parent node.
- */
- static public function get_node_parent_by_type( $node, $type = '' ) {
- // Get node object if node ID set
- if ( ! is_object( $node ) ) {
- $node = self::get_node( $node );
- }
- // Return early if no node object found or node has no parent
- if ( empty( $node ) || empty( $node->parent ) ) {
- return;
- }
- // Helper array of parent types and their categories for each node type
- $parent_types = array(
- 'module' => array(
- 'type' => 'column',
- 'category' => 'columns',
- ),
- 'column' => array(
- 'type' => 'column-group',
- 'category' => 'groups',
- ),
- 'column-group' => array(
- 'type' => 'row',
- 'category' => 'rows',
- ),
- );
- // Helper array of node type hierarchies
- $hierarchy = array(
- 'module' => 10,
- 'column' => 20,
- 'column-group' => 30,
- 'row' => 40,
- );
- // Set immediate parent type of the node when:
- // - type is not of allowed types
- // - type is the same as node type
- // - type is lower in hierarchy than the node type
- if ( ! in_array( $type, array_keys( $hierarchy ) ) || $type == $node->type || $hierarchy[ $parent_types[ $node->type ]['type'] ] > $hierarchy[ $type ] ) {
- $type = $parent_types[ $node->type ]['type'];
- }
- // Get all layout nodes, categorized
- $nodes = array_filter( self::get_categorized_nodes() );
- // Null out the output initially
- $output = '';
- // Parse layout nodes to get the correct output
- if ( ! empty( $nodes ) ) {
- while ( empty( $output ) ) {
- if ( ! empty( $node->parent ) && isset( $nodes[ $parent_types[ $node->type ]['category'] ] ) ) {
- $break_while = true;
- foreach ( $nodes[ $parent_types[ $node->type ]['category'] ] as $parent ) {
- if ( $parent->node == $node->parent ) {
- $break_while = false;
- if ( $parent_types[ $node->type ]['type'] == $type ) {
- // We have got the type we wanted! Set the output and break from while and foreach loops.
- $output = $parent;
- break; // From foreach
- }
- // We now need node parents to crawl the tree
- $node = $parent;
- break; // From foreach
- }
- }
- // If we get this far without changing $break_while, something is wrong
- if ( $break_while ) {
- break; // From while
- }
- } else {
- break; // From while
- }
- }
- }
- return $output;
- }
- /**
- * Returns an array of child nodes for a parent.
- *
- * @since 1.0
- * @param string|object $parent_id Either the parent node id or parent node object.
- * @param string $status The node status. Either draft or published.
- * @return array
- */
- static public function get_child_nodes( $parent_id, $status = null ) {
- $parent = is_object( $parent_id ) ? $parent_id : self::get_node( $parent_id );
- $template_post_id = self::is_node_global( $parent );
- $template_node_id = null;
- $status = $template_post_id && ! self::is_post_node_template() ? 'published' : $status;
- $data = self::get_layout_data( $status, $template_post_id );
- $nodes = array();
- if ( $template_post_id ) {
- $template_node_id = apply_filters( 'fl_builder_parent_template_node_id', $parent->template_node_id, $parent, $data );
- }
- if ( is_object( $parent ) ) {
- foreach ( $data as $node_id => $node ) {
- if ( ( isset( $node->parent ) && $node->parent == $parent->node )
- || ( $template_node_id && $template_node_id == $node->parent ) ) {
- $nodes[ $node_id ] = $node;
- }
- }
- }
- return $nodes;
- }
- /**
- * Returns all child nodes and children of those children
- * for a single node.
- *
- * @since 1.6.3
- * @param string $parent_id The parent node id.
- * @return array
- */
- static public function get_nested_nodes( $parent_id ) {
- $children = self::get_child_nodes( $parent_id );
- foreach ( $children as $child_id => $child ) {
- $grand_children = self::get_child_nodes( $child_id );
- if ( count( $grand_children ) > 0 ) {
- $children = array_merge( $children, $grand_children );
- foreach ( $grand_children as $grand_child_id => $grand_child ) {
- $nested = self::get_nested_nodes( $grand_child_id );
- if ( count( $nested ) > 0 ) {
- $children = array_merge( $children, $nested );
- }
- }
- }
- }
- return $children;
- }
- /**
- * Returns an array of all nodes for a layout, categorized by type.
- *
- * @since 1.6.3
- * @return array
- */
- static public function get_categorized_nodes() {
- $nodes = array(
- 'rows' => array(),
- 'groups' => array(),
- 'columns' => array(),
- 'modules' => array(),
- );
- if ( self::is_post_user_template( 'module' ) ) {
- $nodes['modules'] = self::get_all_modules();
- } elseif ( self::is_post_user_template( 'column' ) ) {
- $root_col = self::get_node_template_root( 'column' );
- $nodes['columns'][ $root_col->node ] = $root_col;
- $col_children = self::get_nodes( null, $root_col );
- foreach ( $col_children as $col_child ) {
- if ( 'module' == $col_child->type ) {
- $module = self::get_module( $col_child );
- if ( $module ) {
- $nodes['modules'][ $col_child->node ] = $module;
- }
- } elseif ( 'column-group' == $col_child->type ) {
- $nodes['groups'][ $col_child->node ] = $col_child;
- $group_cols = self::get_nodes( 'column', $col_child );
- foreach ( $group_cols as $group_col ) {
- $nodes['columns'][ $group_col->node ] = $group_col;
- $modules = self::get_modules( $group_col );
- foreach ( $modules as $module ) {
- $nodes['modules'][ $module->node ] = $module;
- }
- }
- }
- }
- } else {
- $rows = self::get_nodes( 'row' );
- foreach ( $rows as $row ) {
- $nodes['rows'][ $row->node ] = $row;
- $groups = self::get_nodes( 'column-group', $row );
- foreach ( $groups as $group ) {
- $nodes['groups'][ $group->node ] = $group;
- $cols = self::get_nodes( 'column', $group );
- foreach ( $cols as $col ) {
- $nodes['columns'][ $col->node ] = $col;
- $col_children = self::get_nodes( null, $col );
- foreach ( $col_children as $col_child ) {
- if ( 'module' == $col_child->type ) {
- $module = self::get_module( $col_child );
- if ( $module ) {
- $nodes['modules'][ $col_child->node ] = $module;
- }
- } elseif ( 'column-group' == $col_child->type ) {
- $nodes['groups'][ $col_child->node ] = $col_child;
- $group_cols = self::get_nodes( 'column', $col_child );
- foreach ( $group_cols as $group_col ) {
- $nodes['columns'][ $group_col->node ] = $group_col;
- $modules = self::get_modules( $group_col );
- foreach ( $modules as $module ) {
- $nodes['modules'][ $module->node ] = $module;
- }
- }
- }
- }
- }
- }
- }
- }
- return $nodes;
- }
- /**
- * Returns node settings that are merged with the
- * default or preview settings.
- *
- * @since 1.0
- * @param object|string $node A node object or node ID.
- * @param bool $filter Whether to filter the settings or not.
- * @return object
- */
- static public function get_node_settings( $node, $filter = true ) {
- $node = is_object( $node ) ? $node : self::get_node( $node );
- $post_data = self::get_post_data();
- // Get the node settings for a node template's root node?
- if ( self::is_node_template_root( $node ) && ! self::is_post_node_template() ) {
- $template_post_id = self::get_node_template_post_id( $node->template_id );
- $template_data = self::get_layout_data( 'published', $template_post_id );
- // Fallback to draft data if we don't have published data.
- if ( ! isset( $template_data[ $node->template_node_id ] ) ) {
- $template_data = self::get_layout_data( 'draft', $template_post_id );
- }
- // Set the node settings to the template node settings.
- if ( isset( $template_data[ $node->template_node_id ] ) ) {
- $template_node = $template_data[ $node->template_node_id ];
- $template_settings = clone $template_node->settings;
- if ( 'column' == $node->type ) {
- $template_settings->size = $node->settings->size;
- }
- $node->settings = $template_settings;
- }
- }
- // Get either the preview settings or saved node settings merged with the defaults.
- if ( isset( $post_data['node_preview'] ) && isset( $post_data['node_id'] ) && $post_data['node_id'] == $node->node ) {
- if ( ! isset( $post_data['node_preview_processed_settings'] ) ) {
- $settings = $post_data['node_preview'];
- $settings = (object) array_merge( (array) $node->settings, (array) $settings );
- $settings = self::process_node_settings( $node, $settings );
- self::update_post_data( 'node_preview_processed_settings', $settings );
- } else {
- $settings = $post_data['node_preview_processed_settings'];
- }
- } else {
- $defaults = self::get_node_defaults( $node );
- $settings = (object) array_merge( (array) $defaults, (array) $node->settings );
- if ( 'module' == $node->type ) {
- $settings = self::merge_nested_module_defaults( $node->settings->type, $settings );
- } elseif ( 'column' == $node->type ) {
- $settings = self::merge_nested_form_defaults( 'general', 'col', $settings );
- } elseif ( 'row' == $node->type ) {
- $settings = self::merge_nested_form_defaults( 'general', 'row', $settings );
- }
- }
- return ! $filter ? $settings : apply_filters( 'fl_builder_node_settings', $settings, $node );
- }
- /**
- * Returns node settings that have been processed with
- * specific logic based on the type of node.
- *
- * @since 1.0
- * @param object $node A node object.
- * @param object $new_settings The new node settings.
- * @return object
- */
- static public function process_node_settings( $node, $new_settings ) {
- if ( 'row' == $node->type ) {
- $new_settings = self::process_row_settings( $node, $new_settings );
- $new_settings = self::sanitize_settings( $new_settings, 'row', 'general' );
- }
- if ( 'column' == $node->type ) {
- $new_settings = self::process_col_settings( $node, $new_settings );
- $new_settings = self::sanitize_settings( $new_settings, 'col', 'general' );
- }
- if ( 'module' == $node->type ) {
- $new_settings = self::process_module_settings( $node, $new_settings );
- $new_settings = self::sanitize_settings( $new_settings, $node->settings->type, 'module' );
- }
- return $new_settings;
- }
- /**
- * Returns the default settings for a node.
- *
- * @since 1.0
- * @param object $node A node object.
- * @return object
- */
- static public function get_node_defaults( $node ) {
- $defaults = array();
- if ( 'row' == $node->type ) {
- $defaults = self::get_row_defaults();
- } elseif ( 'column' == $node->type ) {
- $defaults = self::get_col_defaults();
- } elseif ( 'module' == $node->type ) {
- $defaults = self::get_module_defaults( $node->settings->type );
- }
- return $defaults;
- }
- /**
- * Callback for the uasort function.
- *
- * @since 1.0
- * @param int $a The first position.
- * @param int $b The second position.
- * @return int
- */
- static public function order_nodes( $a, $b ) {
- return (int) $a->position - (int) $b->position;
- }
- /**
- * Counts the number of nodes in a parent.
- *
- * @since 1.0
- * @param string $type The type of nodes to count.
- * @param string $parent_id The parent node id.
- * @return int
- */
- static public function count_nodes( $type = 'row', $parent_id = null ) {
- return count( self::get_nodes( $type, $parent_id ) );
- }
- /**
- * Returns the index of the next available
- * position in a parent node.
- *
- * @since 1.0
- * @param string $type The type of nodes to count.
- * @param string $parent_id The parent node id.
- * @return int
- */
- static public function next_node_position( $type = 'row', $parent_id = null ) {
- $nodes = self::get_nodes( $type, $parent_id );
- $last = array_pop( $nodes );
- return $last ? $last->position + 1 : 0;
- }
- /**
- * Deletes a node.
- *
- * @since 1.0
- * @param string $node_id The ID of the node to delete.
- * @return void
- */
- static public function delete_node( $node_id = null ) {
- // Get the layout data.
- $data = self::get_layout_data();
- // Return if the node doesn't exist.
- if ( ! isset( $data[ $node_id ] ) ) {
- return;
- }
- // Get the node.
- $node = $data[ $node_id ];
- // Call the delete method if we're deleting a module.
- self::call_module_delete( $node );
- // Delete the node.
- unset( $data[ $node_id ] );
- // Get the sibling nodes.
- if ( 'row' === $node->type ) {
- $siblings = self::get_nodes( 'row' );
- } else {
- $siblings = self::get_nodes( null, $node->parent );
- }
- // Reorder sibling nodes.
- $position = 0;
- foreach ( $siblings as $sibling_id => $sibling ) {
- if ( isset( $data[ $sibling_id ] ) ) {
- $data[ $sibling_id ]->position = $position;
- $position++;
- }
- }
- // Delete the node's children.
- self::delete_child_nodes_from_data( $node, $data );
- // Update the layout data.
- self::update_layout_data( $data );
- }
- /**
- * Deletes all child nodes for a parent.
- *
- * @since 1.0
- * @param object $parent The parent node object.
- * @param object $data The data array to delete from.
- * @return void
- */
- static public function delete_child_nodes_from_data( $parent = null, &$data ) {
- $children = self::get_nodes( null, $parent );
- foreach ( $children as $child_id => $child ) {
- // Call the delete method if we're deleting a module.
- self::call_module_delete( $child );
- // Delete the node.
- unset( $data[ $child_id ] );
- // Delete the node's children.
- self::delete_child_nodes_from_data( $child, $data );
- }
- }
- /**
- * Calls the delete method for a node
- * that is a module.
- *
- * @since 1.0
- * @param object $node A module node.
- * @return void
- */
- static public function call_module_delete( $node ) {
- if ( 'module' == $node->type && isset( self::$modules[ $node->settings->type ] ) ) {
- $class = get_class( self::$modules[ $node->settings->type ] );
- $instance = new $class();
- $instance->node = $node->node;
- $instance->parent = $node->parent;
- $instance->settings = $node->settings;
- $instance->delete();
- $instance->remove();
- }
- }
- /**
- * Repositions a node within a parent.
- *
- * @since 1.0
- * @param string $node_id A node ID.
- * @param int $position The new position.
- * @param string $type The type of node to order.
- * @return void
- */
- static public function reorder_node( $node_id = null, $position = 0 ) {
- $data = self::get_layout_data();
- $node = $data[ $node_id ];
- $type = ! $node->parent ? $node->type : null;
- $nodes = self::get_nodes( $type, $node->parent );
- $new_pos = 0;
- // Make sure node positions start at zero.
- foreach ( $nodes as $node ) {
- $data[ $node->node ]->position = $new_pos;
- $new_pos++;
- }
- // Get the node and remove it from the array.
- $node = $data[ $node_id ];
- $removed = array_splice( $nodes, $node->position, 1 );
- $new_pos = 0;
- // Reposition it in the array.
- array_splice( $nodes, $position, 0, $removed );
- // Update the position data.
- foreach ( $nodes as $node ) {
- $data[ $node->node ]->position = $new_pos;
- $new_pos++;
- }
- // Update the layout data.
- self::update_layout_data( $data );
- }
- /**
- * Moves a node to another parent.
- *
- * @since 1.0
- * @param string $node_id ID of the node to move.
- * @param int $new_parent_id ID of the new parent.
- * @param int $position The position in the new parent.
- * @return void
- */
- static public function move_node( $node_id = null, $new_parent_id = null, $position = 0 ) {
- $data = self::get_layout_data();
- $new_parent = self::get_node( $new_parent_id );
- $node = self::get_node( $node_id );
- $siblings = self::get_nodes( null, $node->parent );
- $sibling_pos = 0;
- // Set the node's new parent.
- $data[ $node_id ]->parent = $new_parent->node;
- // Remove the node from the $siblings array.
- unset( $siblings[ $node_id ] );
- // Reorder old siblings.
- foreach ( $siblings as $sibling ) {
- $data[ $sibling->node ]->position = $sibling_pos;
- $sibling_pos++;
- }
- // Update the layout data.
- self::update_layout_data( $data );
- // Set the node's new order.
- self::reorder_node( $node_id, $position );
- }
- /**
- * Adds a row to the current layout.
- *
- * @since 1.0
- * @param string $cols The type of column layout to use.
- * @param int $position The position of the new row.
- * @return object The new row object.
- */
- static public function add_row( $cols = '1-col', $position = false ) {
- $data = self::get_layout_data();
- $settings = self::get_row_defaults();
- $row_node_id = self::generate_node_id();
- // Add the row.
- $data[ $row_node_id ] = new StdClass();
- $data[ $row_node_id ]->node = $row_node_id;
- $data[ $row_node_id ]->type = 'row';
- $data[ $row_node_id ]->parent = null;
- $data[ $row_node_id ]->position = self::next_node_position( 'row' );
- $data[ $row_node_id ]->settings = $settings;
- // Update the layout data.
- self::update_layout_data( $data );
- // Position the row.
- if ( false !== $position ) {
- self::reorder_node( $row_node_id, $position );
- }
- // Add a column group.
- self::add_col_group( $row_node_id, $cols, 0 );
- // Return the updated row.
- return self::get_node( $row_node_id );
- }
- /**
- * Copys a row and adds it to the current layout.
- *
- * @since 1.0
- * @param string $node_id Node ID of the row to copy.
- * @param object $settings These settings will be used for the copy if present.
- * @param string $settings_id The ID of the node who's settings were passed.
- * @return void
- */
- static public function copy_row( $node_id = null, $settings = null, $settings_id = null ) {
- $layout_data = self::get_layout_data();
- $row = self::get_node( $node_id );
- $new_row_id = self::generate_node_id();
- $col_groups = self::get_nodes( 'column-group', $row );
- $new_nodes = array();
- $template_cols = array();
- // Add the new row.
- $layout_data[ $new_row_id ] = clone $row;
- $layout_data[ $new_row_id ]->settings = clone $row->settings;
- $layout_data[ $new_row_id ]->node = $new_row_id;
- // Unset row template data.
- if ( isset( $layout_data[ $new_row_id ]->template_id ) ) {
- unset( $layout_data[ $new_row_id ]->template_id );
- unset( $layout_data[ $new_row_id ]->template_node_id );
- unset( $layout_data[ $new_row_id ]->template_root_node );
- }
- // Get the new child nodes.
- foreach ( $col_groups as $col_group ) {
- $new_nodes[ $col_group->node ] = clone $col_group;
- $cols = self::get_nodes( 'column', $col_group );
- foreach ( $cols as $col ) {
- $new_nodes[ $col->node ] = clone $col;
- $new_nodes[ $col->node ]->settings = clone $col->settings;
- $nodes = self::get_nodes( null, $col );
- foreach ( $nodes as $node ) {
- $new_nodes[ $node->node ] = clone $node;
- if ( 'module' == $node->type ) {
- $new_nodes[ $node->node ]->settings = self::clone_module_settings( $node->settings );
- } elseif ( 'column-group' == $node->type ) {
- $nested_cols = self::get_nodes( 'column', $node );
- foreach ( $nested_cols as $nested_col ) {
- $new_nodes[ $nested_col->node ] = clone $nested_col;
- $new_nodes[ $nested_col->node ]->settings = clone $nested_col->settings;
- $modules = self::get_nodes( 'module', $nested_col );
- foreach ( $modules as $module ) {
- $new_nodes[ $module->node ] = clone $module;
- $new_nodes[ $module->node ]->settings = self::clone_module_settings( $module->settings );
- }
- }
- }
- }
- }
- }
- // Apply settings that were passed if we have them.
- if ( $settings && $settings_id ) {
- if ( $settings_id === $row->node ) {
- $layout_data[ $new_row_id ]->settings = (object) array_merge( (array) $row->settings, (array) $settings );
- } else {
- $new_nodes[ $settings_id ]->settings = (object) array_merge( (array) $new_nodes[ $settings_id ]->settings, (array) $settings );
- }
- }
- // Generate new child ids.
- $new_nodes = self::generate_new_node_ids( $new_nodes );
- // Set col group parent ids to the new row id and unset template data.
- foreach ( $new_nodes as $child_node_id => $child ) {
- // Check for column template's new node id.
- if ( isset( $child->template_node_id ) ) {
- $template_cols[ $child->template_node_id ] = $child_node_id;
- }
- if ( 'column-group' == $child->type ) {
- if ( $child->parent == $row->node || ( isset( $row->template_node_id ) && $child->parent == $row->template_node_id ) ) {
- $new_nodes[ $child_node_id ]->parent = $new_row_id;
- }
- } elseif ( 'module' == $child->type ) {
- if ( isset( $template_cols[ $child->parent ] ) ) {
- $new_nodes[ $child_node_id ]->parent = $template_cols[ $child->parent ];
- }
- }
- if ( isset( $new_nodes[ $child_node_id ]->template_id ) ) {
- unset( $new_nodes[ $child_node_id ]->template_id );
- unset( $new_nodes[ $child_node_id ]->template_node_id );
- }
- }
- // Merge the child data.
- $layout_data = array_merge( $layout_data, $new_nodes );
- // Update the layout data.
- self::update_layout_data( $layout_data );
- // Position the new row.
- self::reorder_node( $new_row_id, $row->position + 1 );
- // Return the new row.
- return self::get_node( $new_row_id );
- }
- /**
- * Returns the default settings for row nodes.
- *
- * @since 1.0
- * @return object
- */
- static public function get_row_defaults() {
- $settings = self::get_settings_form_defaults( 'row' );
- $settings = self::merge_nested_form_defaults( 'general', 'row', $settings );
- return $settings;
- }
- /**
- * Returns an array of spacing placeholders for row
- * margins and padding.
- *
- * @since 1.9
- * @return array
- */
- static public function get_row_spacing_placeholders() {
- $settings = FLBuilderModel::get_global_settings();
- $placeholders = array();
- // Default.
- $placeholders['row_margins'] = $settings->row_margins;
- $placeholders['row_padding'] = $settings->row_padding;
- // Medium.
- $placeholders['row_margins_medium'] = ( '' != $settings->row_margins_medium ) ? $settings->row_margins_medium : $settings->row_margins;
- $placeholders['row_padding_medium'] = ( '' != $settings->row_padding_medium ) ? $settings->row_padding_medium : $settings->row_padding;
- // Responsive row margins.
- if ( '' != $settings->row_margins_responsive ) {
- $placeholders['row_margins_responsive'] = $settings->row_margins_responsive;
- } elseif ( $settings->auto_spacing ) {
- $placeholders['row_margins_responsive'] = 0;
- } else {
- $placeholders['row_margins_responsive'] = $placeholders['row_margins_medium'];
- }
- // Responsive row padding.
- if ( '' != $settings->row_padding_responsive ) {
- $placeholders['row_padding_tb_responsive'] = $settings->row_padding_responsive;
- $placeholders['row_padding_lr_responsive'] = $settings->row_padding_responsive;
- } elseif ( $settings->auto_spacing ) {
- $placeholders['row_padding_tb_responsive'] = $placeholders['row_padding_medium'];
- $placeholders['row_padding_lr_responsive'] = 0;
- } else {
- $placeholders['row_padding_tb_responsive'] = $placeholders['row_padding_medium'];
- $placeholders['row_padding_lr_responsive'] = $placeholders['row_padding_medium'];
- }
- return $placeholders;
- }
- /**
- * Runs row specific logic on new row settings.
- *
- * @since 1.0
- * @param object $row A row node.
- * @param object $new_settings The new settings object.
- * @return object
- */
- static public function process_row_settings( $row, $new_settings ) {
- // Cache background video data.
- if ( 'video' == $new_settings->bg_type ) {
- // Video Fallback Photo
- if ( ! empty( $new_settings->bg_video_fallback_src ) ) {
- $fallback = $new_settings->bg_video_fallback_src;
- } else {
- $fallback = '';
- }
- if ( 'wordpress' == $new_settings->bg_video_source ) {
- // Video MP4
- $mp4 = FLBuilderPhoto::get_attachment_data( $new_settings->bg_video );
- if ( $mp4 ) {
- $parts = explode( '.', $mp4->filename );
- $mp4->extension = array_pop( $parts );
- $new_settings->bg_video_data = $mp4;
- $new_settings->bg_video_data->fallback = $fallback;
- }
- // Video WebM
- $webm = FLBuilderPhoto::get_attachment_data( $new_settings->bg_video_webm );
- if ( $webm ) {
- $parts = explode( '.', $webm->filename );
- $webm->extension = array_pop( $parts );
- $new_settings->bg_video_webm_data = $webm;
- $new_settings->bg_video_webm_data->fallback = $fallback;
- }
- }
- }
- // Cache background slideshow data.
- if ( 'slideshow' == $new_settings->bg_type && 'wordpress' == $new_settings->ss_source ) {
- // Make sure we have a photo data object.
- if ( ! isset( $row->settings->ss_photo_data ) ) {
- $row->settings->ss_photo_data = new StdClass();
- }
- // Hijack the slideshow module to get WordPress photo data.
- $ss = new FLSlideshowModule();
- $ss->settings = new StdClass();
- $ss->settings->photos = $new_settings->ss_photos;
- $ss->settings->photo_data = $row->settings->ss_photo_data;
- $new_settings->ss_photo_data = $ss->get_wordpress_photos();
- }
- return $new_settings;
- }
- /**
- * Returns background data for a row.
- *
- * @since 1.0
- * @param object $row A row node.
- * @return object
- */
- static public function get_row_bg_data( $row ) {
- $data = null;
- // Background Video
- if ( 'video' == $row->settings->bg_type ) {
- if ( isset( $row->settings->bg_video_data ) ) {
- $data = array();
- $data['mp4'] = $row->settings->bg_video_data;
- }
- if ( isset( $row->settings->bg_video_webm_data ) ) {
- if ( ! $data ) {
- $data = array();
- }
- $data['webm'] = $row->settings->bg_video_webm_data;
- }
- } elseif ( 'slideshow' == $row->settings->bg_type && isset( $row->settings->ss_photo_data ) ) {
- $data = $row->settings->ss_photo_data;
- }
- return $data;
- }
- /**
- * Returns the source for a row background slideshow.
- *
- * @since 1.0
- * @param object $row A row node.
- * @return string
- */
- static public function get_row_slideshow_source( $row ) {
- // Make sure we have a photo data object.
- if ( ! isset( $row->settings->ss_photo_data ) ) {
- $row->settings->ss_photo_data = new StdClass();
- }
- // This class does not exist in Lite version.
- if ( ! class_exists( 'FLSlideshowModule' ) ) {
- return false;
- }
- // Hijack the slideshow module to get the source.
- $ss = new FLSlideshowModule();
- $ss->settings = new StdClass();
- $ss->settings->source = $row->settings->ss_source;
- $ss->settings->photos = $row->settings->ss_photos;
- $ss->settings->feed_url = $row->settings->ss_feed_url;
- $ss->settings->photo_data = $row->settings->ss_photo_data;
- // Return the slideshow source.
- return $ss->get_source();
- }
- /**
- * Set the max-width of a specific row.
- *
- * @since 2.0
- * @param int Row node id
- * @param int Width
- * @return void
- */
- static public function resize_row_content( $node_id, $width ) {
- $data = self::get_layout_data();
- $row = self::get_node( $node_id );
- $row->settings->max_content_width = $width;
- $data[ $node_id ] = $row;
- self::update_layout_data( $data );
- }
- /**
- * Adds a column group to a row in the current layout.
- *
- * @since 1.0
- * @param string $node_id A row node ID.
- * @param string $cols The type of column group layout or the ID of an existing column to add.
- * @param int $position The position of the new column group.
- * @return object The new column group object.
- */
- static public function add_col_group( $node_id = null, $cols = '1-col', $position = false ) {
- $data = self::get_layout_data();
- $group_node_id = self::generate_node_id();
- $parent = self::get_node( $node_id );
- $old_group = null;
- // Add the column group.
- $data[ $group_node_id ] = new StdClass();
- $data[ $group_node_id ]->node = $group_node_id;
- $data[ $group_node_id ]->type = 'column-group';
- $data[ $group_node_id ]->parent = $node_id;
- $data[ $group_node_id ]->position = self::next_node_position( null, $node_id );
- $data[ $group_node_id ]->settings = '';
- // Add node template data.
- if ( self::is_node_global( $parent ) ) {
- $data[ $group_node_id ]->template_id = $parent->template_id;
- $data[ $group_node_id ]->template_node_id = $group_node_id;
- }
- // Add new columns?
- if ( isset( self::$row_layouts[ $cols ] ) ) {
- for ( $i = 0; $i < count( self::$row_layouts[ $cols ] ); $i++ ) {
- $col_node_id = self::generate_node_id();
- $data[ $col_node_id ] = new StdClass();
- $data[ $col_node_id ]->node = $col_node_id;
- $data[ $col_node_id ]->type = 'column';
- $data[ $col_node_id ]->parent = $group_node_id;
- $data[ $col_node_id ]->position = $i;
- $data[ $col_node_id ]->settings = new StdClass();
- $data[ $col_node_id ]->settings->size = self::$row_layouts[ $cols ][ $i ];
- if ( self::is_node_global( $parent ) ) {
- $data[ $col_node_id ]->template_id = $parent->template_id;
- $data[ $col_node_id ]->template_node_id = $col_node_id;
- }
- }
- } elseif ( isset( $data[ $cols ] ) ) {
- $old_group = $data[ $cols ]->parent;
- $siblings = self::get_nodes( 'column', $old_group );
- $sibling_pos = 0;
- // Add the column to the group.
- $data[ $cols ]->parent = $group_node_id;
- $data[ $cols ]->position = 0;
- $data[ $cols ]->settings->size = 100;
- if ( self::is_node_global( $parent ) ) {
- $data[ $cols ]->template_id = $parent->template_id;
- $data[ $cols ]->template_node_id = $data[ $cols ]->node;
- }
- // Remove the column from the $siblings array.
- unset( $siblings[ $cols ] );
- // Reorder old siblings.
- foreach ( $siblings as $sibling ) {
- $data[ $sibling->node ]->position = $sibling_pos;
- $sibling_pos++;
- }
- }
- // Update the layout data.
- self::update_layout_data( $data );
- // Delete an existing column's old group if empty or resize it.
- if ( $old_group ) {
- if ( 0 === count( self::get_nodes( 'column', $old_group ) ) ) {
- self::delete_node( $old_group );
- } else {
- self::reset_col_widths( $old_group );
- }
- }
- // Position the column group.
- if ( false !== $position ) {
- self::reorder_node( $group_node_id, $position );
- }
- // Return the column group.
- return self::get_node( $group_node_id );
- }
- /**
- * Runs column specific logic on new column settings.
- *
- * @since 1.0
- * @param object $col A column node.
- * @param object $new_settings The new settings object.
- * @return object
- */
- static public function process_col_settings( $col, $new_settings ) {
- $post_data = self::get_post_data();
- // Don't process for preview nodes.
- if ( isset( $post_data['node_preview'] ) ) {
- return $new_settings;
- }
- // Resize sibling cols if needed.
- $new_settings->size = self::resize_col( $col->node, $new_settings->size );
- // Update other sibling vars as needed.
- $equal_height = false;
- $content_alignment = false;
- $responsive_order = false;
- // Adjust sibling equal height?
- if ( $col->settings->equal_height != $new_settings->equal_height ) {
- $equal_height = $new_settings->equal_height;
- }
- // Adjust sibling content alignment?
- if ( $col->settings->content_alignment != $new_settings->content_alignment ) {
- $content_alignment = $new_settings->content_alignment;
- }
- // Adjust sibling responsive order?
- if ( $col->settings->responsive_order != $new_settings->responsive_order ) {
- $responsive_order = $new_settings->responsive_order;
- }
- // Update the siblings?
- if ( false !== $equal_height || false !== $content_alignment || false !== $responsive_order ) {
- $data = self::get_layout_data();
- $cols = self::get_nodes( 'column', $col->parent );
- foreach ( $cols as $node_id => $node ) {
- if ( false !== $equal_height ) {
- $data[ $node_id ]->settings->equal_height = $equal_height;
- }
- if ( false !== $content_alignment ) {
- $data[ $node_id ]->settings->content_alignment = $content_alignment;
- }
- if ( false !== $responsive_order ) {
- $data[ $node_id ]->settings->responsive_order = $responsive_order;
- }
- }
- self::update_layout_data( $data );
- }
- return $new_settings;
- }
- /**
- * Deletes a column.
- *
- * @since 1.0
- * @param string $node_id Node ID of the column to delete (can also be a group).
- * @param int $new_width New width of the remaining columns.
- * @return void
- */
- static public function delete_col( $node_id = null, $new_width = 100 ) {
- $col = self::get_node( $node_id );
- // Delete the column.
- self::delete_node( $node_id );
- // Return if the node we just deleted was a group.
- if ( 'column-group' == $col->type ) {
- return;
- }
- // Get the group
- $group = self::get_node( $col->parent );
- // Get the group children.
- $cols = self::get_nodes( 'column', $group->node );
- // Delete the group if empty.
- if ( count( $cols ) === 0 ) {
- self::delete_node( $group->node );
- } else {
- // Get the layout data.
- $data = self::get_layout_data();
- // Loop through the columns.
- foreach ( $cols as $col_id => $col ) {
- // Set the new size.
- $data[ $col_id ]->settings->size = round( $new_width, 3 );
- }
- // Update the layout data.
- self::update_layout_data( $data );
- }
- }
- /**
- * Moves a column within a group.
- *
- * @since 1.9
- * @param string $node_id
- * @param int $position
- * @return void
- */
- static public function reorder_col( $node_id, $position = 0 ) {
- $col = self::get_node( $node_id );
- self::reorder_node( $node_id, $position );
- self::reset_col_widths( $col->parent );
- }
- /**
- * Moves a column from one group to another.
- *
- * @since 1.9
- * @param string $col_id
- * @param string $group_id
- * @param int $position
- * @param array $resize
- * @return void
- */
- static public function move_col( $col_id, $group_id, $position, $resize = array() ) {
- $col = self::get_node( $col_id );
- $old_group = self::get_node( $col->parent );
- self::move_node( $col_id, $group_id, $position );
- if ( 0 === count( self::get_nodes( 'column', $old_group ) ) ) {
- self::delete_node( $old_group->node );
- self::reset_col_widths( $group_id );
- } else {
- self::reset_col_widths( $resize );
- }
- }
- /**
- * Resizes a column.
- *
- * @since 1.0
- * @param string $node_id Node ID of the column to resize.
- * @param int $new_width New width of the column.
- * @return int The new width
- */
- static public function resize_col( $node_id = null, $new_width = 100 ) {
- $data = self::get_layout_data();
- $col = $data[ $node_id ];
- $group = $data[ $col->parent ];
- $cols = array_values( self::get_nodes( 'column', $group->node ) );
- $pos = $col->position;
- $siblings = array();
- $siblings_width = 0;
- $num_cols = count( $cols );
- $min_width = 8;
- $max_width = 100 - $min_width;
- // Don't resize if only one column or width isn't a number.
- if ( 1 == $num_cols || ! is_numeric( $new_width ) ) {
- return $col->settings->size;
- }
- // Find the sibling column to absorb this resize.
- for ( $i = 0; $i < count( $cols ); $i++ ) {
- if ( $col->node == $cols[ $i ]->node ) {
- if ( isset( $cols[ $i + 1 ] ) ) {
- $sibling = $cols[ $i + 1 ];
- } else {
- $sibling = $cols[ $i - 1 ];
- }
- break;
- }
- }
- // Find other siblings.
- foreach ( $cols as $c ) {
- if ( $col->node == $c->node ) {
- continue;
- }
- if ( $sibling->node == $c->node ) {
- continue;
- }
- $siblings[] = $c;
- $max_width -= $c->settings->size;
- $siblings_width += $c->settings->size;
- }
- // Make sure the new width isn't too small.
- if ( $new_width < $min_width ) {
- $new_width = $min_width;
- }
- // Make sure the new width isn't too big.
- if ( $new_width > $max_width ) {
- $new_width = $max_width;
- }
- // Save new sibling size.
- $data[ $sibling->node ]->settings->size = round( 100 - $siblings_width - $new_width, 3 );
- // Save new column size.
- $data[ $col->node ]->settings->size = $new_width;
- // Update the layout data.
- self::update_layout_data( $data );
- // Return the new size.
- return $new_width;
- }
- /**
- * Resizes a column and its sibling using the provided widths.
- *
- * @since 1.6.4
- * @param string $col_id Node ID of the column to resize.
- * @param int $col_width New width of the column.
- * @param string $sibling_id Node ID of the sibling to resize.
- * @param int $sibling_width New width of the sibling.
- * @return void
- */
- static public function resize_cols( $col_id = null, $col_width = null, $sibling_id = null, $sibling_width = null ) {
- $data = self::get_layout_data();
- // Save the column width.
- $data[ $col_id ]->settings->size = $col_width;
- // Save the sibling width.
- $data[ $sibling_id ]->settings->size = $sibling_width;
- // Update the layout data.
- self::update_layout_data( $data );
- }
- /**
- * Resets the widths of all columns in a group.
- *
- * @since 1.6.4
- * @param string|array $group_id Node ID of the group whose columns to reset or an array of group IDs.
- * @return void
- */
- static public function reset_col_widths( $group_id = null ) {
- if ( 'array' == gettype( $group_id ) ) {
- foreach ( $group_id as $id ) {
- self::reset_col_widths( $id );
- }
- return;
- }
- $data = self::get_layout_data();
- $post_data = self::get_post_data();
- $cols = self::get_nodes( 'column', $group_id );
- $width = round( 100 / count( $cols ), 3 );
- foreach ( $cols as $col_id => $col ) {
- $data[ $col_id ]->settings->size = $width;
- }
- self::update_layout_data( $data );
- }
- /**
- * Adds a column to a column group in the current layout.
- *
- * @since 1.9
- * @param string $node_id A column group node ID.
- * @param int $position The position of the new column.
- * @return object The new column object.
- */
- static public function add_col( $node_id = null, $position = false ) {
- $group = self::get_node( $node_id );
- $cols = self::get_nodes( 'column', $group );
- $num_cols = count( $cols );
- $i = 0;
- $sibling = false;
- $insert = 'before';
- foreach ( $cols as $col ) {
- if ( $i == $position ) {
- $sibling = $col;
- break;
- }
- $i++;
- }
- if ( ! $sibling ) {
- $sibling = $col;
- $insert = 'after';
- }
- self::add_cols( $sibling->node, $insert );
- $cols = self::get_nodes( 'column', $group );
- $col_ids = array_keys( $cols );
- return $cols[ $col_ids[ $position ] ];
- }
- /**
- * Inserts a column (or columns) before or after another column.
- *
- * @since 1.6.4
- * @param string $node_id Node ID of the column to insert before or after.
- * @param string $insert Either before or after.
- * @param string $type The type of column(s) to insert.
- * @param boolean $nested Whether these columns are nested or not.
- * @return object
- */
- static public function add_cols( $col_id, $insert = 'before', $type = '1-col', $nested = false ) {
- $data = self::get_layout_data();
- $col = self::get_node( $col_id );
- $parent = self::get_node( $col->parent );
- $cols = self::get_nodes( 'column', $col->parent );
- $global = self::is_node_global( $parent );
- $num_new_cols = count( self::$row_layouts[ $type ] );
- $num_cols = count( $cols );
- $max_cols = $nested ? 4 : 12;
- $reposition = false;
- $position = 0;
- // Make sure we have 12 columns or less.
- if ( $num_cols + $num_new_cols > $max_cols ) {
- $num_new_cols = $num_new_cols - ( $num_cols + $num_new_cols - $max_cols );
- $num_cols = $max_cols;
- } else {
- $num_cols += $num_new_cols;
- }
- // Get the new width.
- if ( 6 === $num_cols ) {
- $new_width = 16.65;
- } elseif ( 7 === $num_cols ) {
- $new_width = 14.28;
- } else {
- $new_width = round( 100 / $num_cols, 3 );
- }
- // Get the new column position.
- if ( 'before' == $insert ) {
- $new_col_position = $col->position - 1 < 0 ? 0 : $col->position;
- } else {
- $new_col_position = $col->position + 1;
- }
- // Add the new columns.
- for ( $i = 0; $i < $num_new_cols; $i++ ) {
- $new_col_id = self::generate_node_id();
- $data[ $new_col_id ] = new StdClass();
- $data[ $new_col_id ]->node = $new_col_id;
- $data[ $new_col_id ]->type = 'column';
- $data[ $new_col_id ]->parent = $parent->node;
- $data[ $new_col_id ]->position = $new_col_position;
- $data[ $new_col_id ]->settings = new StdClass();
- $data[ $new_col_id ]->settings->size = $new_width;
- // Add node template data.
- if ( $global ) {
- $data[ $new_col_id ]->template_id = $parent->template_id;
- $data[ $new_col_id ]->template_node_id = $new_col_id;
- }
- $new_col_position++;
- }
- // Resize sibling columns and set their new position.
- foreach ( $cols as $sibling_col_id => $sibling_col ) {
- $data[ $sibling_col_id ]->settings->size = $new_width;
- if ( $sibling_col_id == $col_id ) {
- $reposition = true;
- if ( 'before' == $insert ) {
- $data[ $sibling_col_id ]->position = $new_col_position;
- $new_col_position++;
- }
- } elseif ( $reposition ) {
- $data[ $sibling_col_id ]->position = $new_col_position;
- $new_col_position++;
- } else {
- $data[ $sibling_col_id ]->position = $position;
- $position++;
- }
- }
- // Update the layout data.
- self::update_layout_data( $data );
- // Return the column group.
- return $parent;
- }
- /**
- * Adds a parent node for a column if a parent with the supplied
- * parent ID doesn't exist.
- *
- * @since 2.1
- * @param string $parent_id The node ID of the parent to look for.
- * @param int $position The position of the parent.
- * @return string|null The new parent ID or null if none exists.
- */
- static public function add_col_parent( $parent_id = null, $position = null ) {
- $data = self::get_layout_data();
- $parent = ! $parent_id ? null : self::get_node( $parent_id );
- if ( ! $parent ) {
- // Add a new row if we don't have a parent, but don't add column.
- $row = self::add_row( null, $position );
- $col_groups = self::get_nodes( 'column-group', $row->node );
- $col_group = array_shift( $col_groups );
- $parent_id = $col_group->node;
- } elseif ( 'row' == $parent->type ) {
- // Add a new column group if the parent is a row, but don't add column.
- $col_group = self::add_col_group( $parent->node, null, $position );
- $parent_id = $col_group->node;
- }
- return $parent_id;
- }
- /**
- * Returns a column's parent node of the specified type.
- *
- * @since 2.1
- * @param string $type The type of parent to return.
- * @param string|object $column_id The columns's node ID. Can also be a column object.
- * @return object The parent node.
- */
- static public function get_col_parent( $type, $column_id ) {
- $column = is_object( $column_id ) ? $column_id : self::get_node( $column_id );
- $nodes = self::get_categorized_nodes();
- foreach ( $nodes['groups'] as $group ) {
- if ( $group->node == $column->parent ) {
- if ( 'column-group' == $type ) {
- return $group;
- }
- foreach ( $nodes['rows'] as $row ) {
- if ( $row->node == $group->parent ) {
- return $row;
- }
- }
- }
- }
- return null;
- }
- /**
- * Copys a column and adds it to the current layout.
- *
- * @since 2.0
- * @param string $node_id Node ID of the column to copy.
- * @param object $settings These settings will be used for the copy if present.
- * @param string $settings_id The ID of the node who's settings were passed.
- * @return void
- */
- static public function copy_col( $node_id = null, $settings = null, $settings_id = null ) {
- $layout_data = self::get_layout_data();
- $col = self::get_node( $node_id );
- $new_col_id = self::generate_node_id();
- $nodes = self::get_nodes( null, $col );
- $parent = self::get_node_parent( $node_id );
- $new_nodes = array();
- // Add the new column.
- $layout_data[ $new_col_id ] = clone $col;
- $layout_data[ $new_col_id ]->settings = clone $col->settings;
- $layout_data[ $new_col_id ]->node = $new_col_id;
- // Unset column template data.
- if ( isset( $layout_data[ $new_col_id ]->template_id ) ) {
- // Get the column root parent on a page.
- if ( isset( $layout_data[ $new_col_id ]->template_root_node ) ) {
- $parent = self::get_node( $layout_data[ $new_col_id ]->parent );
- }
- // Check if parent is a global node.
- if ( self::is_node_global( $parent ) ) {
- $layout_data[ $new_col_id ]->template_id = $parent->template_id;
- $layout_data[ $new_col_id ]->template_node_id = $new_col_id;
- } else {
- unset( $layout_data[ $new_col_id ]->template_id );
- unset( $layout_data[ $new_col_id ]->template_node_id );
- }
- unset( $layout_data[ $new_col_id ]->template_root_node );
- }
- // Get the new child nodes.
- foreach ( $nodes as $node ) {
- $new_nodes[ $node->node ] = clone $node;
- if ( 'module' == $node->type ) {
- $new_nodes[ $node->node ]->settings = self::clone_module_settings( $node->settings );
- } elseif ( 'column-group' == $node->type ) {
- $nested_cols = self::get_nodes( 'column', $node );
- foreach ( $nested_cols as $nested_col ) {
- $new_nodes[ $nested_col->node ] = clone $nested_col;
- $new_nodes[ $nested_col->node ]->settings = clone $nested_col->settings;
- $modules = self::get_nodes( 'module', $nested_col );
- foreach ( $modules as $module ) {
- $new_nodes[ $module->node ] = clone $module;
- $new_nodes[ $module->node ]->settings = self::clone_module_settings( $module->settings );
- }
- }
- }
- }
- // Apply settings that were passed if we have them.
- if ( $settings && $settings_id ) {
- if ( $settings_id === $col->node ) {
- $layout_data[ $new_col_id ]->settings = (object) array_merge( (array) $col->settings, (array) $settings );
- } else {
- $new_nodes[ $settings_id ]->settings = (object) array_merge( (array) $new_nodes[ $settings_id ]->settings, (array) $settings );
- }
- }
- // Generate new child ids.
- $new_nodes = self::generate_new_node_ids( $new_nodes );
- // Set child parent ids to the new column id and unset template data.
- foreach ( $new_nodes as $child_node_id => $child ) {
- if ( $child->parent == $col->node || ( isset( $col->template_node_id ) && $child->parent == $col->template_node_id ) ) {
- $new_nodes[ $child_node_id ]->parent = $new_col_id;
- }
- if ( isset( $new_nodes[ $child_node_id ]->template_id ) ) {
- // Check if the column is global.
- if ( isset( $layout_data[ $new_col_id ]->template_node_id ) ) {
- $new_nodes[ $child_node_id ]->template_id = $parent->template_id;
- $new_nodes[ $child_node_id ]->template_node_id = $child_node_id;
- } else {
- unset( $new_nodes[ $child_node_id ]->template_id );
- unset( $new_nodes[ $child_node_id ]->template_node_id );
- }
- }
- }
- // Merge the child data.
- $layout_data = array_merge( $layout_data, $new_nodes );
- // Update the layout data.
- self::update_layout_data( $layout_data );
- // Position the new column.
- self::reorder_node( $new_col_id, $col->position + 1 );
- // Reset the column widths.
- self::reset_col_widths( $col->parent );
- // Return the new column.
- return self::get_node( $new_col_id );
- }
- /**
- * Returns the default settings for column nodes.
- *
- * @since 1.0
- * @return object
- */
- static public function get_col_defaults() {
- $settings = self::get_settings_form_defaults( 'col' );
- $settings = self::merge_nested_form_defaults( 'general', 'col', $settings );
- return $settings;
- }
- /**
- * Loads the classes for core builder modules.
- *
- * @since 1.0
- * @return void
- */
- static public function load_modules() {
- $paths = glob( FL_BUILDER_DIR . 'modules/*' );
- $module_path = '';
- // Make sure we have an array.
- if ( ! is_array( $paths ) ) {
- return;
- }
- // Load all found modules.
- foreach ( $paths as $path ) {
- // Make sure we have a directory.
- if ( ! is_dir( $path ) ) {
- continue;
- }
- // Get the module slug.
- $slug = basename( $path );
- // Paths to check.
- $module_path = $slug . '/' . $slug . '.php';
- $child_path = get_stylesheet_directory() . '/fl-builder/modules/' . $module_path;
- $theme_path = get_template_directory() . '/fl-builder/modules/' . $module_path;
- $builder_path = FL_BUILDER_DIR . 'modules/' . $module_path;
- // Check for the module class in a child theme.
- if ( is_child_theme() && file_exists( $child_path ) ) {
- require_once $child_path;
- } elseif ( file_exists( $theme_path ) ) {
- require_once $theme_path;
- } elseif ( file_exists( $builder_path ) ) {
- require_once $builder_path;
- }
- }
- do_action( 'fl_builder_register_extensions' );
- }
- /**
- * Registers a module with the builder.
- *
- * @since 1.0
- * @param string $class The module's PHP class name.
- * @param array $form The module's settings form.
- * @return void
- */
- static public function register_module( $class, $form ) {
- if ( class_exists( $class ) ) {
- // Create a new instance of the module.
- $instance = new $class();
- // Log an error if a module with this slug already exists.
- if ( isset( self::$modules[ $instance->slug ] ) ) {
- error_log( sprintf( _x( 'A module with the filename %s.php already exists! Please namespace your module filenames to ensure compatibility with Beaver Builder.', '%s stands for the module filename', 'fl-builder' ), $instance->slug ) );
- return;
- }
- /**
- * Use this filter to override the modules that are enabled in the builder.
- * @see fl_builder_register_module
- * @link https://kb.wpbeaverbuilder.com/article/117-plugin-filter-reference
- */
- $instance->enabled = apply_filters( 'fl_builder_register_module', $instance->enabled, $instance );
- // Save the instance in the modules array.
- self::$modules[ $instance->slug ] = $instance;
- /**
- * Use this filter to modify the config array for a settings form when it is registered.
- * @see fl_builder_register_settings_form
- * @link https://kb.wpbeaverbuilder.com/article/117-plugin-filter-reference
- */
- self::$modules[ $instance->slug ]->form = apply_filters( 'fl_builder_register_settings_form', $form, $instance->slug );
- self::$modules[ $instance->slug ]->form['advanced'] = self::$settings_forms['module_advanced'];
- }
- }
- /**
- * Registers an alias to a module with its own name,
- * category and default settings.
- *
- * @since 1.10
- * @param string $alias The alias key.
- * @param array $config The alias config.
- * @return void
- */
- static public function register_module_alias( $alias, $config ) {
- if ( isset( self::$module_aliases[ $alias ] ) ) {
- _doing_it_wrong( __CLASS__ . '::register_module_alias', sprintf( _x( 'The module alias %s already exists! Please namespace your module aliases to ensure compatibility with Beaver Builder.', '%s stands for the module alias key', 'fl-builder' ), $alias ), '1.10' );
- return;
- }
- $instance = new stdClass;
- $instance->alias = $alias;
- $instance->slug = isset( $config['module'] ) ? $config['module'] : null;
- $instance->name = isset( $config['name'] ) ? $config['name'] : $slug;
- $instance->description = isset( $config['description'] ) ? $config['description'] : '';
- $instance->category = isset( $config['category'] ) ? $config['category'] : null;
- $instance->group = isset( $config['group'] ) ? $config['group'] : null;
- $instance->settings = isset( $config['settings'] ) ? $config['settings'] : array();
- $instance->enabled = isset( $config['enabled'] ) ? $config['enabled'] : true;
- $instance->icon = isset( $config['icon'] ) ? $config['icon'] : FLBuilderModule::get_default_icon();
- self::$module_aliases[ $alias ] = $instance;
- }
- /**
- * Returns the default settings for a module alias.
- *
- * @since 1.10
- * @param string $alias The alias key.
- * @return array|null
- */
- static public function get_module_alias_settings( $alias ) {
- if ( isset( self::$module_aliases[ $alias ] ) ) {
- return self::$module_aliases[ $alias ]->settings;
- }
- return null;
- }
- /**
- * Checks to see if a module of a certain type has
- * been registered.
- *
- * @since 1.9
- * @param array $type The module's type slug.
- * @return void
- */
- static public function is_module_registered( $type ) {
- return isset( self::$modules[ $type ] );
- }
- /**
- * Returns an array of modules that are enabled by default.
- *
- * @since 2.1
- * @return array
- */
- static public function get_default_enabled_modules() {
- $default = array_keys( self::$modules );
- // These modules are deprecated and disabled by default.
- $deprecated = array(
- 'social-buttons',
- );
- // Remove deprecated modules from the defaults.
- foreach ( $default as $key => $slug ) {
- if ( in_array( $slug, $deprecated ) ) {
- unset( $default[ $key ] );
- }
- }
- return array_values( $default );
- }
- /**
- * Returns an array of all modules that are enabled.
- *
- * @since 1.0
- * @return array
- */
- static public function get_enabled_modules() {
- $setting = self::get_admin_settings_option( '_fl_builder_enabled_modules', true );
- if ( ! $setting ) {
- // Fallback to the defaults if no saved setting.
- $setting = self::get_default_enabled_modules();
- } elseif ( in_array( 'all', $setting ) ) {
- // Redefine $setting in case new modules have been installed since the last save.
- $setting = array_keys( self::$modules );
- $setting[] = 'all';
- }
- foreach ( self::$modules as $module_slug => $module ) {
- if ( ! $module->enabled && in_array( $module_slug, $setting ) ) {
- $key = array_search( $module_slug, $setting );
- unset( $setting[ $key ] );
- }
- }
- return apply_filters( 'fl_builder_enabled_modules', $setting );
- }
- /**
- * Returns an array of module group slugs and names.
- *
- * @since 2.0
- * @return array
- */
- static public function get_module_groups() {
- $groups = array();
- $templates = FLBuilderModel::get_module_templates_data();
- // Add module groups.
- foreach ( self::$modules as $module ) {
- if ( ! $module->group || ! $module->enabled ) {
- continue;
- }
- // Check if widgets are enabled
- if ( 'widget' == $module->slug && ! in_array( 'widget', self::get_enabled_modules() ) ) {
- continue;
- }
- $slug = sanitize_key( $module->group );
- if ( ! isset( $groups[ $slug ] ) ) {
- $groups[ $slug ] = $module->group;
- }
- }
- // Add module template groups.
- if ( isset( $templates['groups'] ) ) {
- foreach ( $templates['groups'] as $slug => $data ) {
- if ( ! isset( $groups[ $slug ] ) ) {
- $groups[ $slug ] = $data['name'];
- }
- }
- }
- return $groups;
- }
- /**
- * Returns an array of module category slugs => names
- *
- * @since 2.0
- * @return array
- */
- static public function get_module_categories() {
- $categories = array();
- /**
- * Use this filter to add custom module categories that will show up before the default module categories in the builder’s UI.
- * @see fl_builder_module_categories
- * @link https://kb.wpbeaverbuilder.com/article/117-plugin-filter-reference
- */
- foreach ( apply_filters( 'fl_builder_module_categories', array() ) as $custom_category ) {
- $categories[ $custom_category ] = array();
- }
- // Build the default category arrays.
- $categories[ __( 'Basic', 'fl-builder' ) ] = array();
- $categories[ __( 'Media', 'fl-builder' ) ] = array();
- $categories[ __( 'Actions', 'fl-builder' ) ] = array();
- $categories[ __( 'Layout', 'fl-builder' ) ] = array();
- $categories[ __( 'Info', 'fl-builder' ) ] = array();
- $categories[ __( 'Posts', 'fl-builder' ) ] = array();
- $categories[ __( 'Advanced', 'fl-builder' ) ] = array();
- $categories[ __( 'Other', 'fl-builder' ) ] = array();
- return $categories;
- }
- /**
- * Returns an array of categorized modules.
- *
- * @since 1.0
- * @param bool $show_disabled Whether to include disabled modules in the result.
- * @return array
- */
- static public function get_categorized_modules( $show_disabled = false ) {
- $enabled_modules = self::get_enabled_modules();
- $widgets = null;
- $categories = self::get_module_categories();
- $other_key = __( 'Other', 'fl-builder' );
- $widgets_key = __( 'WordPress Widgets', 'fl-builder' );
- // Build the categories array.
- foreach ( self::$modules as $module ) {
- if ( ! $module->enabled ) {
- continue;
- } elseif ( ! in_array( $module->slug, $enabled_modules ) && ! $show_disabled ) {
- continue;
- } elseif ( 'widget' == $module->slug ) {
- $widgets = self::get_wp_widgets();
- } elseif ( isset( $module->category ) ) {
- if ( ! isset( $categories[ $module->category ] ) ) {
- $categories[ $module->category ] = array();
- }
- $categories[ $module->category ][ $module->name ] = $module;
- } else {
- $categories[ $other_key ][ $module->name ] = $module;
- }
- }
- // Add module aliases.
- foreach ( self::$module_aliases as $alias => $config ) {
- if ( ! $config->enabled || ! $config->slug || ! $config->category ) {
- continue;
- }
- if ( ! isset( $categories[ $config->category ] ) ) {
- $categories[ $config->category ] = array();
- }
- $categories[ $config->category ][ $config->name ] = $config;
- }
- // Add widgets if we have them.
- if ( $widgets ) {
- $categories[ $widgets_key ] = $widgets;
- }
- // Sort the modules.
- foreach ( $categories as $title => $modules ) {
- if ( count( $categories[ $title ] ) == 0 ) {
- unset( $categories[ $title ] );
- } else {
- ksort( $categories[ $title ] );
- }
- }
- // Return sorted categories.
- return $categories;
- }
- /**
- * Similar to get_categorized_modules() but creates a flat list.
- *
- * @since 2.0
- * @param bool $show_disabled Should show disabled?
- * @return array
- */
- static public function get_uncategorized_modules( $show_disabled = false ) {
- $enabled_modules = self::get_enabled_modules();
- $modules = array();
- $aliases = self::$module_aliases;
- $widgets = FLBuilderModel::get_wp_widgets();
- foreach ( self::$modules as $module ) {
- if ( ! $module->enabled ) {
- continue;
- } elseif ( ! in_array( $module->slug, $enabled_modules ) && ! $show_disabled ) {
- continue;
- } elseif ( 'widget' === $module->slug ) {
- continue;
- }
- $module = clone (object) $module;
- $module->kind = 'module';
- $module->isWidget = false; // @codingStandardsIgnoreLine
- $module->isAlias = false; // @codingStandardsIgnoreLine
- $module->group = $module->group ? array( sanitize_key( $module->group ) ) : array( 'standard' );
- if ( ! isset( $module->icon ) || '' == $module->icon ) {
- $module->icon = FLBuilderModule::get_default_icon();
- }
- // Remove backend-only & instance properties.
- unset( $module->css );
- unset( $module->js );
- unset( $module->editor_export );
- unset( $module->node );
- unset( $module->parent );
- unset( $module->partial_refresh );
- unset( $module->position );
- unset( $module->settings );
- unset( $module->form );
- unset( $module->dir );
- $modules[] = $module;
- }
- // Add module aliases.
- foreach ( $aliases as $alias => $config ) {
- if ( ! $config->enabled || ! $config->slug || ! $config->category ) {
- continue;
- }
- if ( ! isset( $categories[ $config->category ] ) ) {
- $categories[ $config->category ] = array();
- }
- $config->kind = 'module';
- $config->isWidget = false; // @codingStandardsIgnoreLine
- $config->isAlias = true; // @codingStandardsIgnoreLine
- $config->group = $config->group ? array( sanitize_key( $config->group ) ) : array( 'standard' );
- $modules[] = $config;
- }
- // Add WordPress widgets.
- if ( in_array( 'widget', $enabled_modules ) ) {
- foreach ( $widgets as $widget ) {
- $data = new stdClass;
- $widget = (object) $widget;
- $data->id = $widget->id;
- $data->name = $widget->name;
- $data->class = $widget->class;
- $data->category = $widget->category;
- $data->kind = 'module';
- $data->isWidget = true; // @codingStandardsIgnoreLine
- $data->isAlias = false; // @codingStandardsIgnoreLine
- $data->description = isset( $widget->widget_options['description'] ) ? $widget->widget_options['description'] : '';
- $data->group = array( sanitize_key( __( 'WordPress Widgets', 'fl-builder' ) ) );
- if ( ! isset( $widget->icon ) ) {
- $data->icon = FLBuilderModule::get_widget_icon();
- }
- $modules[] = $data;
- }
- }
- return $modules;
- }
- /**
- * Returns an instance of a module.
- *
- * @since 1.0
- * @param string|object $node_id A module node ID or object.
- * @return object|bool The module or false if it doesn't exist.
- */
- static public function get_module( $node_id ) {
- $module = is_object( $node_id ) ? $node_id : self::get_node( $node_id );
- if ( self::is_module_registered( $module->settings->type ) ) {
- $class = get_class( self::$modules[ $module->settings->type ] );
- $instance = new $class();
- $instance->node = $module->node;
- $instance->parent = $module->parent;
- $instance->position = $module->position;
- $instance->settings = $module->settings;
- $instance->type = 'module';
- $instance->form = self::$modules[ $module->settings->type ]->form;
- $instance->icon = isset( $module->icon ) ? $module->icon : FLBuilderModule::get_default_icon();
- if ( isset( $module->template_id ) ) {
- $instance->template_id = $module->template_id;
- $instance->template_node_id = $module->template_node_id;
- }
- if ( isset( $module->template_root_node ) ) {
- $instance->template_root_node = true;
- }
- return $instance;
- }
- return false;
- }
- /**
- * Returns an array of all modules in the current layout
- * or in a column if a column id or object is supplied.
- *
- * @since 1.0
- * @param string|object $col_id A column ID or object.
- * @return array
- */
- static public function get_modules( $col_id = null ) {
- $col = is_object( $col_id ) ? $col_id : self::get_node( $col_id );
- $modules = self::get_nodes( 'module', $col );
- $instances = array();
- $i = 0;
- foreach ( $modules as $module ) {
- if ( self::is_module_registered( $module->settings->type ) ) {
- $class = get_class( self::$modules[ $module->settings->type ] );
- $instances[ $i ] = new $class();
- $instances[ $i ]->node = $module->node;
- $instances[ $i ]->parent = $module->parent;
- $instances[ $i ]->position = $module->position;
- $instances[ $i ]->settings = $module->settings;
- $instances[ $i ]->type = 'module';
- $instances[ $i ]->icon = isset( $module->icon ) ? $module->icon : FLBuilderModule::get_default_icon();
- $instances[ $i ]->form = self::$modules[ $module->settings->type ]->form;
- if ( isset( $module->template_id ) ) {
- $instances[ $i ]->template_id = $module->template_id;
- $instances[ $i ]->template_node_id = $module->template_node_id;
- }
- if ( isset( $module->template_root_node ) ) {
- $instances[ $i ]->template_root_node = true;
- }
- $i++;
- }
- }
- return $instances;
- }
- /**
- * Returns an array of all modules in the current layout.
- *
- * @since 1.0
- * @return array
- */
- static public function get_all_modules() {
- return self::get_modules();
- }
- /**
- * Add a new module to a column in the current layout.
- *
- * @since 1.0
- * @param string $type The type of module to add.
- * @param array $settings The new module's settings.
- * @param string $parent_id The new module's parent node ID.
- * @param int $position The new module's position.
- * @return object The new module object.
- */
- static public function add_module( $type = null, $settings = array(), $parent_id = null, $position = false ) {
- $data = self::get_layout_data();
- $parent = self::get_node( $parent_id );
- $module_node_id = self::generate_node_id();
- $settings->type = $type;
- // Run module update method.
- $class = get_class( self::$modules[ $type ] );
- $instance = new $class();
- $instance->node = $module_node_id;
- $instance->settings = $settings;
- $settings = $instance->update( $settings );
- // Save the module.
- $data[ $module_node_id ] = new StdClass();
- $data[ $module_node_id ]->node = $module_node_id;
- $data[ $module_node_id ]->type = 'module';
- $data[ $module_node_id ]->parent = $parent_id;
- $data[ $module_node_id ]->position = self::next_node_position( 'module', $parent_id );
- $data[ $module_node_id ]->settings = $settings;
- // Add node template data.
- if ( self::is_node_global( $parent ) ) {
- $data[ $module_node_id ]->template_id = $parent->template_id;
- $data[ $module_node_id ]->template_node_id = $module_node_id;
- }
- // Update the layout data.
- self::update_layout_data( $data );
- // Position the module.
- if ( false !== $position ) {
- self::reorder_node( $module_node_id, $position );
- }
- // Send back the inserted module.
- return self::get_module( $module_node_id );
- }
- /**
- * Adds a parent node for a module if a parent with the supplied
- * parent ID doesn't exist.
- *
- * @since 1.6.3
- * @param string $parent_id The node ID of the parent to look for.
- * @param int $position The position of the parent.
- * @return string|null The new parent ID or null if none exists.
- */
- static public function add_module_parent( $parent_id = null, $position = null ) {
- $parent = ! $parent_id ? null : self::get_node( $parent_id );
- if ( ! $parent ) {
- // Add a new row if we don't have a parent.
- $row = self::add_row( '1-col', $position );
- $col_groups = self::get_nodes( 'column-group', $row->node );
- $col_group = array_shift( $col_groups );
- $cols = self::get_nodes( 'column', $col_group->node );
- $parent = array_shift( $cols );
- $parent_id = $parent->node;
- } elseif ( 'row' == $parent->type ) {
- // Add a new column group if the parent is a row.
- $col_group = self::add_col_group( $parent->node, '1-col', $position );
- $cols = self::get_nodes( 'column', $col_group->node );
- $parent = array_shift( $cols );
- $parent_id = $parent->node;
- } elseif ( 'column-group' == $parent->type ) {
- // Add a new column if the parent is a column group.
- $parent = self::add_col( $parent->node, $position );
- $parent_id = $parent->node;
- }
- return $parent_id;
- }
- /**
- * Returns a module's parent node of the specified type.
- *
- * @since 1.7
- * @param string $type The type of parent to return.
- * @param string|object $module_id The module's node ID. Can also be a module object.
- * @return object The parent node.
- */
- static public function get_module_parent( $type, $module_id ) {
- $module = is_object( $module_id ) ? $module_id : self::get_module( $module_id );
- $nodes = self::get_categorized_nodes();
- foreach ( $nodes['columns'] as $column ) {
- if ( $column->node == $module->parent ) {
- if ( 'column' == $type ) {
- return $column;
- }
- foreach ( $nodes['groups'] as $group ) {
- if ( $group->node == $column->parent ) {
- if ( 'column-group' == $type ) {
- return $group;
- }
- foreach ( $nodes['rows'] as $row ) {
- if ( $row->node == $group->parent ) {
- return $row;
- }
- }
- }
- }
- }
- }
- return null;
- }
- /**
- * Add a new module with default settings to a column
- * in the current layout.
- *
- * @since 1.0
- * @param string $parent_id The new module's parent node ID.
- * @param string $type The type of module to add.
- * @param int $position The new module's position.
- * @return object The new module object.
- * @return array $defaults Default settings for the module.
- */
- static public function add_default_module( $parent_id = null, $type = null, $position = null, $defaults = null ) {
- $parent = ( 0 == $parent_id ) ? null : self::get_node( $parent_id );
- $settings = self::get_module_defaults( $type );
- $module_node_id = self::generate_node_id();
- // Add a new parent if one is needed.
- if ( ! $parent || 'row' == $parent->type || 'column-group' == $parent->type ) {
- $parent_id = self::add_module_parent( $parent_id, $position );
- $parent = self::get_node( $parent_id );
- $position = null;
- }
- // Merge default settings if present.
- if ( $defaults ) {
- $settings = (object) array_merge( (array) $settings, $defaults );
- }
- // Run module update method.
- $class = get_class( self::$modules[ $type ] );
- $instance = new $class();
- $instance->node = $module_node_id;
- $instance->settings = $settings;
- $settings = $instance->update( $settings );
- // Save the module.
- $data = self::get_layout_data();
- $data[ $module_node_id ] = new StdClass();
- $data[ $module_node_id ]->node = $module_node_id;
- $data[ $module_node_id ]->type = 'module';
- $data[ $module_node_id ]->parent = $parent_id;
- $data[ $module_node_id ]->position = self::next_node_position( 'module', $parent_id );
- $data[ $module_node_id ]->settings = $settings;
- // Add node template data.
- if ( self::is_node_global( $parent ) ) {
- $data[ $module_node_id ]->template_id = $parent->template_id;
- $data[ $module_node_id ]->template_node_id = $module_node_id;
- }
- // Update the layout data.
- self::update_layout_data( $data );
- // Position the module.
- if ( null !== $position ) {
- self::reorder_node( $module_node_id, $position );
- }
- // Send back the inserted module.
- return self::get_module( $module_node_id );
- }
- /**
- * Make a copy of a module.
- *
- * @since 1.0
- * @param string $node_id Node ID of the module to copy.
- * @param object $settings These settings will be used for the copy if present.
- * @return object The new module object.
- */
- static public function copy_module( $node_id = null, $settings = null ) {
- $module = self::get_module( $node_id );
- if ( $settings ) {
- $module->settings = (object) array_merge( (array) $module->settings, (array) $settings );
- }
- return self::add_module( $module->settings->type, $module->settings, $module->parent, $module->position + 1 );
- }
- /**
- * Run module specific logic on new node settings.
- *
- * @since 1.0
- * @param object $module A module node object.
- * @param object $new_settings The new settings.
- * @return object
- */
- static public function process_module_settings( $module, $new_settings ) {
- // Get a new node instance to work with.
- $class = get_class( self::$modules[ $module->settings->type ] );
- $instance = new $class();
- $instance->node = $module->node;
- $instance->parent = $module->parent;
- $instance->settings = $module->settings;
- // Run node delete to clear any cache.
- $instance->delete();
- // Run node update.
- $instance->settings = $new_settings;
- $new_settings = $instance->update( $new_settings );
- return $new_settings;
- }
- /**
- * Returns a cloned settings object for a module.
- *
- * @since 1.9
- * @param object $settings
- * @return object
- */
- static public function clone_module_settings( $settings ) {
- $new_settings = new stdClass;
- foreach ( $settings as $key => $val ) {
- $new_settings->$key = $val;
- }
- return $new_settings;
- }
- /**
- * Returns the default settings for a module or
- * all modules if type is null.
- *
- * @since 1.0
- * @param string $type The type of module.
- * @return object|array
- */
- static public function get_module_defaults( $type = null ) {
- if ( $type ) {
- $defaults = new StdClass();
- if ( isset( self::$modules[ $type ]->form ) ) {
- $defaults = self::get_settings_form_defaults( $type );
- $defaults = self::merge_nested_module_defaults( $type, $defaults );
- $defaults->type = $type;
- }
- } else {
- $defaults = array();
- foreach ( self::$modules as $module ) {
- $defaults[ $module->slug ] = self::get_module_defaults( $module->slug );
- }
- }
- return $defaults;
- }
- /**
- * Merges the default settings for nested forms in a module.
- *
- * @since 1.7
- * @param string $type The type of module.
- * @param object $settings The module settings object.
- * @return object
- */
- static public function merge_nested_module_defaults( $type, $settings ) {
- return self::merge_nested_form_defaults( 'module', $type, $settings );
- }
- /**
- * Returns an array of data for each core WordPress widget.
- *
- * @since 1.0
- * @return array
- */
- static public function get_wp_widgets() {
- global $wp_widget_factory;
- $widgets = array();
- // These are known widgets that won't work in the builder.
- $exclude = apply_filters( 'fl_get_wp_widgets_exclude', array(
- 'WP_Widget_Media_Audio',
- 'WP_Widget_Media_Image',
- 'WP_Widget_Media_Video',
- 'WP_Widget_Media_Gallery',
- 'WP_Widget_Text',
- 'WP_Widget_Custom_HTML',
- ) );
- foreach ( $wp_widget_factory->widgets as $class => $widget ) {
- if ( in_array( $class, $exclude ) ) {
- continue;
- }
- $widget->class = $class;
- $widget->isWidget = true; // @codingStandardsIgnoreLine
- $widget->category = __( 'WordPress Widgets', 'fl-builder' );
- $widgets[ $widget->name ] = $widget;
- }
- ksort( $widgets );
- return $widgets;
- }
- /**
- * Returns an array of data for all registered sidebars.
- *
- * @since 1.0
- * @return array
- */
- static public function get_wp_sidebars() {
- global $wp_registered_sidebars;
- $sidebars = array();
- foreach ( $wp_registered_sidebars as $sidebar ) {
- $sidebars[ $sidebar['name'] ] = $sidebar;
- }
- ksort( $sidebars );
- return $sidebars;
- }
- /**
- * Returns an array of column group data.
- *
- * @since 2.0
- * @return array
- */
- static public function get_column_groups() {
- $cols = array(
- array(
- 'name' => __( '1 Column', 'fl-builder' ),
- 'id' => '1-col',
- 'count' => 1,
- ),
- array(
- 'name' => __( '2 Columns', 'fl-builder' ),
- 'id' => '2-cols',
- 'count' => 2,
- ),
- array(
- 'name' => __( '3 Columns', 'fl-builder' ),
- 'id' => '3-cols',
- 'count' => 3,
- ),
- array(
- 'name' => __( '4 Columns', 'fl-builder' ),
- 'id' => '4-cols',
- 'count' => 4,
- ),
- array(
- 'name' => __( '5 Columns', 'fl-builder' ),
- 'id' => '5-cols',
- 'count' => 5,
- ),
- array(
- 'name' => __( '6 Columns', 'fl-builder' ),
- 'id' => '6-cols',
- 'count' => 6,
- ),
- array(
- 'name' => __( 'Left Sidebar', 'fl-builder' ),
- 'id' => 'left-sidebar',
- 'count' => 2,
- ),
- array(
- 'name' => __( 'Right Sidebar', 'fl-builder' ),
- 'id' => 'right-sidebar',
- 'count' => 2,
- ),
- array(
- 'name' => __( 'Left & Right Sidebar', 'fl-builder' ),
- 'id' => 'left-right-sidebar',
- 'count' => 3,
- ),
- );
- return $cols;
- }
- /**
- * Loads the files for all core builder settings.
- *
- * @since 1.0
- * @return void
- */
- static public function load_settings() {
- require_once FL_BUILDER_DIR . 'includes/global-settings.php';
- require_once FL_BUILDER_DIR . 'includes/layout-settings.php';
- require_once FL_BUILDER_DIR . 'includes/row-settings.php';
- require_once FL_BUILDER_DIR . 'includes/column-settings.php';
- require_once FL_BUILDER_DIR . 'includes/module-settings.php';
- }
- /**
- * Register a settings form with the builder.
- *
- * @since 1.0
- * @param string $id The form id.
- * @param array $form The form data.
- * @return void
- */
- static public function register_settings_form( $id, $form ) {
- /**
- * Use this filter to modify the config array for a settings form when it is registered.
- * @see fl_builder_register_settings_form
- * @link https://kb.wpbeaverbuilder.com/article/117-plugin-filter-reference
- */
- self::$settings_forms[ $id ] = apply_filters( 'fl_builder_register_settings_form', $form, $id );
- // Since 2.0 we need to store the form ID on each tab to ensure that
- // it's always available for rendering forms in JS on the frontend.
- if ( isset( self::$settings_forms[ $id ]['tabs'] ) ) {
- foreach ( self::$settings_forms[ $id ]['tabs'] as $tab_id => $tab ) {
- self::$settings_forms[ $id ]['tabs'][ $tab_id ]['form_id'] = $id;
- }
- } else {
- self::$settings_forms[ $id ]['form_id'] = $id;
- }
- }
- /**
- * Returns the data for a settings form.
- *
- * @since 1.0
- * @param string $id The form id.
- * @return array
- */
- static public function get_settings_form( $id ) {
- return isset( self::$settings_forms[ $id ] ) ? self::$settings_forms[ $id ] : false;
- }
- /**
- * Returns an array of fields in a settings form.
- *
- * @since 1.0
- * @param array|string $form The form data array or the form key. If key, group must be set as well.
- * @param string The form group. Either general or module.
- * @return array
- */
- static public function get_settings_form_fields( $form, $group = null ) {
- $fields = array();
- if ( 'string' === gettype( $form ) ) {
- if ( 'general' === $group ) {
- $form = FLBuilderModel::$settings_forms[ $form ]['tabs'];
- } elseif ( 'module' === $group ) {
- $form = FLBuilderModel::$modules[ $form ]->form;
- } else {
- return $fields;
- }
- }
- foreach ( (array) $form as $tab ) {
- if ( isset( $tab['sections'] ) ) {
- foreach ( $tab['sections'] as $section ) {
- if ( isset( $section['fields'] ) ) {
- foreach ( $section['fields'] as $name => $field ) {
- $fields[ $name ] = $field;
- }
- }
- }
- }
- }
- return $fields;
- }
- /**
- * Returns a settings object with the defaults for a form.
- *
- * @since 1.0
- * @param string $type The type of form.
- * @return object
- */
- static public function get_settings_form_defaults( $type ) {
- // Check to see if the defaults are cached first.
- if ( isset( self::$settings_form_defaults[ $type ] ) ) {
- return self::$settings_form_defaults[ $type ];
- }
- // They aren't cached, let's get them.
- $defaults = new StdClass();
- // Check the registered forms first.
- if ( isset( self::$settings_forms[ $type ] ) ) {
- $form_type = $type;
- $tabs = self::$settings_forms[ $type ]['tabs'];
- } elseif ( isset( self::$modules[ $type ] ) ) {
- $form_type = $type . '-module';
- $tabs = self::$modules[ $type ]->form;
- } else {
- return $defaults;
- }
- // Get the fields.
- $fields = self::get_settings_form_fields( $tabs );
- // Handle dimension fields. We have to do it this way for backwards compat
- // with old margin, padding, and border fields as the settings expect margin_top
- // or margin_bottom to exist instead of just the margin key.
- foreach ( $fields as $name => $field ) {
- if ( 'dimension' == $field['type'] ) {
- foreach ( array( 'top', 'right', 'bottom', 'left' ) as $position ) {
- $fields[ $name . '_' . $position ] = $field;
- }
- unset( $fields[ $name ] );
- }
- }
- // Loop through the fields and get the defaults.
- foreach ( $fields as $name => $field ) {
- $default = isset( $field['default'] ) ? $field['default'] : '';
- $is_multiple = isset( $field['multiple'] ) && true === $field['multiple'];
- $supports_multiple = 'editor' != $field['type'] && 'photo' != $field['type'];
- $responsive = isset( $field['responsive'] ) && $field['responsive'] ? $field['responsive'] : false;
- $responsive_name = '';
- if ( $is_multiple && $supports_multiple ) {
- $defaults->$name = is_array( $default ) ? $default : array( $default );
- } elseif ( $responsive ) {
- foreach ( array( 'default', 'medium', 'responsive' ) as $device ) {
- $responsive_name = $name . ( 'default' == $device ? '' : '_' . $device );
- if ( is_array( $responsive ) && isset( $responsive['default'] ) && isset( $responsive['default'][ $device ] ) ) {
- $defaults->{ $responsive_name } = $responsive['default'][ $device ];
- } elseif ( 'default' == $device ) {
- $defaults->$name = $default;
- } else {
- $defaults->{ $responsive_name } = '';
- }
- }
- } else {
- $defaults->$name = $default;
- }
- }
- /**
- * Use this filter to change the defaults for any of the settings forms in the builder including global, row, column and module settings.
- * @see fl_builder_settings_form_defaults
- * @link https://kb.wpbeaverbuilder.com/article/117-plugin-filter-reference
- */
- self::$settings_form_defaults[ $type ] = apply_filters( 'fl_builder_settings_form_defaults', $defaults, $form_type );
- return self::$settings_form_defaults[ $type ];
- }
- /**
- * Merges the default settings for nested forms.
- *
- * @since 1.10.8
- * @param string $type The type of form. Either general or module.
- * @param string $form The form ID.
- * @param object $settings The module settings object.
- * @return object
- */
- static public function merge_nested_form_defaults( $type, $form, $settings ) {
- // Get the fields.
- if ( 'module' === $type && isset( self::$modules[ $form ] ) ) {
- $fields = self::get_settings_form_fields( self::$modules[ $form ]->form );
- } elseif ( isset( self::$settings_forms[ $form ] ) ) {
- $fields = self::get_settings_form_fields( self::$settings_forms[ $form ]['tabs'] );
- } else {
- return $settings;
- }
- // Loop through the settings.
- foreach ( $settings as $key => $val ) {
- // Make sure this field is a nested form.
- if ( ! isset( $fields[ $key ]['form'] ) ) {
- continue;
- }
- // Get the nested form defaults.
- $nested_defaults = self::get_settings_form_defaults( $fields[ $key ]['form'] );
- // Merge the defaults.
- if ( is_array( $val ) ) {
- foreach ( $val as $nested_key => $nested_val ) {
- $settings->{ $key }[ $nested_key ] = (object) array_merge( (array) $nested_defaults, (array) $nested_val );
- }
- } elseif ( ! empty( $settings->{ $key } ) ) {
- $settings->{ $key } = (object) array_merge( (array) $nested_defaults, (array) $settings->{ $key } );
- } else {
- $settings->{ $key } = (object) $nested_defaults;
- }
- }
- return $settings;
- }
- /**
- * Save the settings for a node.
- *
- * @since 1.0
- * @param string $node_id The node ID.
- * @param object $settings The settings to save.
- * @return void
- */
- static public function save_settings( $node_id = null, $settings = null ) {
- $node = self::get_node( $node_id );
- $new_settings = (object) array_merge( (array) $node->settings, (array) $settings );
- $template_post_id = self::is_node_global( $node );
- // Process the settings.
- $new_settings = self::process_node_settings( $node, $new_settings );
- // Save the settings to the node.
- $data = self::get_layout_data();
- $data[ $node_id ]->settings = $new_settings;
- // Update the layout data.
- self::update_layout_data( $data );
- // Save settings for a global node template?
- if ( $template_post_id && ! self::is_post_node_template() ) {
- // Get the template data.
- $template_data = self::get_layout_data( 'published', $template_post_id );
- // Update the template node settings.
- $template_data[ $node->template_node_id ]->settings = $new_settings;
- // Save the template data.
- self::update_layout_data( $template_data, 'published', $template_post_id );
- self::update_layout_data( $template_data, 'draft', $template_post_id );
- // Delete the template asset cache.
- self::delete_all_asset_cache( $template_post_id );
- self::delete_node_template_asset_cache( $template_post_id );
- }
- // Return the processed settings and new layout.
- return array(
- 'node_id' => $node->node,
- 'settings' => $new_settings,
- 'layout' => FLBuilderAJAXLayout::render(),
- );
- }
- /**
- * Sanitizes settings for a form.
- *
- * @since 2.0
- * @param string $form
- * @param string $group
- * @param object $settings
- * @return object
- */
- static public function sanitize_settings( $settings, $form, $group ) {
- $fields = FLBuilderModel::get_settings_form_fields( $form, $group );
- foreach ( $settings as $name => $value ) {
- if ( ! isset( $fields[ $name ] ) ) {
- continue;
- } elseif ( isset( $fields[ $name ]['sanitize'] ) ) {
- $settings->$name = call_user_func_array( $fields[ $name ]['sanitize'], array( $value ) );
- }
- }
- return $settings;
- }
- /**
- * Adds slashes to settings going into the database as WordPress
- * removes them when we save using update_metadata. This is done
- * to ensure slashes in user input aren't removed.
- *
- * @since 1.5.6
- * @param mixed $data The data to slash.
- * @return mixed The slashed data.
- */
- static public function slash_settings( $data ) {
- if ( is_array( $data ) ) {
- foreach ( $data as $key => $val ) {
- $data[ $key ] = self::slash_settings( $val );
- }
- } elseif ( is_object( $data ) ) {
- foreach ( $data as $key => $val ) {
- $data->$key = self::slash_settings( $val );
- }
- } elseif ( is_string( $data ) ) {
- $data = wp_slash( $data );
- }
- return $data;
- }
- /**
- * Merge defaults into a settings object.
- *
- * @since 1.0
- * @param object $settings Reference to a settings object.
- * @param array $defaults The defaults to merge in.
- * @return void
- */
- static public function default_settings( &$settings, $defaults ) {
- foreach ( $defaults as $name => $value ) {
- if ( ! isset( $settings->$name ) ) {
- $settings->$name = $value;
- }
- }
- }
- /**
- * Get the global builder settings.
- *
- * @since 1.0
- * @return object
- */
- static public function get_global_settings() {
- if ( null === self::$global_settings ) {
- $settings = get_option( '_fl_builder_settings' );
- $defaults = self::get_settings_form_defaults( 'global' );
- if ( ! $settings ) {
- $settings = new StdClass();
- }
- // Merge in defaults and cache settings
- self::$global_settings = (object) array_merge( (array) $defaults, (array) $settings );
- self::$global_settings = self::merge_nested_form_defaults( 'general', 'global', self::$global_settings );
- }
- return self::$global_settings;
- }
- /**
- * Save the global builder settings.
- *
- * @since 1.0
- * @param array $settings The new global settings.
- * @return object
- */
- static public function save_global_settings( $settings = array() ) {
- $old_settings = self::get_global_settings();
- $new_settings = (object) array_merge( (array) $old_settings, (array) $settings );
- self::delete_asset_cache_for_all_posts();
- self::$global_settings = null;
- update_option( '_fl_builder_settings', $new_settings );
- return self::get_global_settings();
- }
- /**
- * Duplicate the current post.
- *
- * @since 1.0
- * @return int The new post ID.
- */
- static public function duplicate_post() {
- global $wpdb;
- $post_id = self::get_post_id();
- $post = get_post( $post_id );
- $current_user = wp_get_current_user();
- $template_id = false;
- // Duplicate the post.
- $data = array(
- 'comment_status' => $post->comment_status,
- 'ping_status' => $post->ping_status,
- 'post_author' => $current_user->ID,
- 'post_content' => $post->post_content,
- 'post_excerpt' => $post->post_excerpt,
- 'post_name' => $post->post_name . '-copy',
- 'post_parent' => $post->post_parent,
- 'post_password' => $post->post_password,
- 'post_status' => 'draft',
- 'post_title' => sprintf( _x( 'Copy of %s', '%s stands for post/page title.', 'fl-builder' ), $post->post_title ),
- 'post_type' => $post->post_type,
- 'to_ping' => $post->to_ping,
- 'menu_order' => $post->menu_order,
- );
- // Get the new post id.
- $new_post_id = wp_insert_post( $data );
- // Duplicate post meta.
- $post_meta = $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id = %d", $post_id ) );
- if ( count( $post_meta ) !== 0 ) {
- $sql = "INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) ";
- foreach ( $post_meta as $meta_info ) {
- $meta_key = $meta_info->meta_key;
- if ( '_fl_builder_template_id' == $meta_key ) {
- $meta_value = self::generate_node_id();
- } else {
- $meta_value = addslashes( $meta_info->meta_value );
- }
- $sql_select[] = "SELECT {$new_post_id}, '{$meta_key}', '{$meta_value}'";
- }
- $sql .= implode( ' UNION ALL ', $sql_select );
- // @codingStandardsIgnoreStart
- $wpdb->query($sql);
- // @codingStandardsIgnoreEnd
- }
- // Duplicate post terms.
- $taxonomies = get_object_taxonomies( $post->post_type );
- foreach ( $taxonomies as $taxonomy ) {
- $post_terms = wp_get_object_terms( $post_id, $taxonomy );
- for ( $i = 0; $i < count( $post_terms ); $i++ ) {
- wp_set_object_terms( $new_post_id, $post_terms[ $i ]->slug, $taxonomy, true );
- }
- }
- // Get the duplicated layout data.
- $data = self::get_layout_data( 'published', $new_post_id );
- // Generate new node ids.
- $data = self::generate_new_node_ids( $data );
- // Update template ID and template node ID
- $template_id = get_post_meta( $new_post_id, '_fl_builder_template_id', true );
- if ( $template_id ) {
- foreach ( $data as $node_id => $node ) {
- $data[ $node_id ]->template_id = $template_id;
- $data[ $node_id ]->template_node_id = $node_id;
- }
- }
- // Save the duplicated layout data.
- self::update_layout_data( $data, 'published', $new_post_id );
- // Also update draft data
- self::update_layout_data( $data, 'draft', $new_post_id );
- // Return the new post id.
- return $new_post_id;
- }
- /**
- * Deletes all layout data and asset cache for a post.
- *
- * @since 1.0
- * @param int $post_id The post ID to delete data and cache for.
- * @return void
- */
- static public function delete_post( $post_id ) {
- // If this is a global template, unlink it from other posts.
- self::unlink_global_node_template_from_all_posts( $post_id );
- // Delete all published and draft data.
- self::delete_layout_data( 'published', $post_id );
- self::delete_layout_data( 'draft', $post_id );
- // Delete all css and js.
- self::delete_all_asset_cache( $post_id );
- }
- /**
- * Save a revision of a builder layout.
- *
- * @since 1.0
- * @param int $post_id
- * @return void
- */
- static public function save_revision( $post_id ) {
- $parent_id = wp_is_post_revision( $post_id );
- if ( $parent_id ) {
- $parent = get_post( $parent_id );
- $data = self::get_layout_data( 'published', $parent->ID );
- $settings = self::get_layout_settings( 'published', $parent->ID );
- if ( ! empty( $data ) ) {
- self::update_layout_data( $data, 'published', $post_id );
- self::update_layout_settings( $settings, 'published', $post_id );
- }
- }
- }
- /**
- * Restore a revision of a builder layout.
- *
- * @since 1.0
- * @param int $post_id
- * @param int $revision_id
- * @return void
- */
- static public function restore_revision( $post_id, $revision_id ) {
- $post = get_post( $post_id );
- $revision = get_post( $revision_id );
- if ( $revision ) {
- $data = self::get_layout_data( 'published', $revision->ID );
- $settings = self::get_layout_settings( 'published', $revision->ID );
- if ( ! empty( $data ) ) {
- self::update_layout_data( $data, 'published', $post_id );
- self::update_layout_data( $data, 'draft', $post_id );
- self::update_layout_settings( $settings, 'published', $post_id );
- self::update_layout_settings( $settings, 'draft', $post_id );
- } else {
- self::delete_layout_data( 'published', $post_id );
- self::delete_layout_data( 'draft', $post_id );
- self::delete_layout_settings( 'published', $post_id );
- self::delete_layout_settings( 'draft', $post_id );
- }
- self::delete_all_asset_cache( $post_id );
- }
- }
- /**
- * Get all of the layout data for a post. We use get_metadata
- * here instead of get_post_meta to ensure revisions are queried accordingly.
- *
- * @since 1.0
- * @param string $status Either published or draft.
- * @param int $post_id The ID of the post to get data for.
- * @return array
- */
- static public function get_layout_data( $status = null, $post_id = null ) {
- $post_id = ! $post_id ? self::get_post_id() : $post_id;
- $status = ! $status ? self::get_node_status() : $status;
- // Get published data?
- if ( 'published' == $status || 'revision' == get_post_type( $post_id ) ) {
- if ( isset( self::$published_layout_data[ $post_id ] ) ) {
- $data = self::$published_layout_data[ $post_id ];
- } else {
- $data = get_metadata( 'post', $post_id, '_fl_builder_data', true );
- $data = self::clean_layout_data( $data );
- self::$published_layout_data[ $post_id ] = apply_filters( 'fl_builder_get_layout_metadata', $data, $status, $post_id );
- }
- } elseif ( 'draft' == $status ) {
- if ( isset( self::$draft_layout_data[ $post_id ] ) ) {
- $data = self::$draft_layout_data[ $post_id ];
- } else {
- $data = get_metadata( 'post', $post_id, '_fl_builder_draft', true );
- $data = self::clean_layout_data( $data );
- self::$draft_layout_data[ $post_id ] = apply_filters( 'fl_builder_get_layout_metadata', $data, $status, $post_id );
- }
- }
- // Make sure we have an array.
- if ( empty( $data ) ) {
- $data = array();
- }
- // Clone the layout data to ensure the cache remains intact.
- foreach ( $data as $node_id => $node ) {
- if ( is_object( $node ) ) {
- $data[ $node_id ] = clone $node;
- }
- }
- // Return the data.
- return apply_filters( 'fl_builder_layout_data', $data, $status, $post_id );
- }
- /**
- * Update the layout data for a post. We use update_metadata
- * here instead of update_post_meta to ensure revisions are updated accordingly.
- *
- * @since 1.0
- * @param array $data The layout data to update.
- * @param string $status Either published or draft.
- * @param int $post_id The ID of the post to update.
- * @return void
- */
- static public function update_layout_data( $data, $status = null, $post_id = null ) {
- $post_id = ! $post_id ? self::get_post_id() : $post_id;
- $status = ! $status ? self::get_node_status() : $status;
- $key = 'published' == $status ? '_fl_builder_data' : '_fl_builder_draft';
- $raw_data = get_metadata( 'post', $post_id, $key );
- $data = self::slash_settings( self::clean_layout_data( $data ) );
- // Update the data.
- if ( 0 === count( $raw_data ) ) {
- add_metadata( 'post', $post_id, $key, $data );
- } else {
- update_metadata( 'post', $post_id, $key, $data );
- }
- // Cache the data.
- if ( 'published' == $status ) {
- self::$published_layout_data[ $post_id ] = $data;
- } elseif ( 'draft' == $status ) {
- self::$draft_layout_data[ $post_id ] = $data;
- }
- }
- /**
- * Delete the layout data for a post.
- *
- * @since 1.0
- * @param string $status Either published or draft.
- * @param int $post_id The ID of the post to delete data.
- * @return void
- */
- static public function delete_layout_data( $status = null, $post_id = null ) {
- // Make sure we have a status to delete.
- if ( ! $status ) {
- return;
- }
- // Get the post id.
- $post_id = ! $post_id ? self::get_post_id() : $post_id;
- // Get the data to delete.
- $data = self::get_layout_data( $status, $post_id );
- // Delete the nodes.
- foreach ( $data as $node ) {
- self::call_module_delete( $node );
- }
- // Update the layout data.
- self::update_layout_data( array(), $status, $post_id );
- }
- /**
- * Ensures the integrity of layout data key/value pairs.
- *
- * Also makes sure we're not serializing any FLBuilderModule
- * instances because those are too big and bloat the data array.
- *
- * @since 1.0
- * @param array $data An array of layout data.
- * @return array
- */
- static public function clean_layout_data( $data = array() ) {
- $cleaned = array();
- if ( is_array( $data ) ) {
- foreach ( $data as $node ) {
- if ( is_object( $node ) && isset( $node->node ) ) {
- if ( is_a( $node, 'FLBuilderModule' ) ) {
- $cleaned[ $node->node ] = new StdClass();
- $cleaned[ $node->node ]->node = $node->node;
- $cleaned[ $node->node ]->type = $node->type;
- $cleaned[ $node->node ]->parent = $node->parent;
- $cleaned[ $node->node ]->position = $node->position;
- $cleaned[ $node->node ]->settings = $node->settings;
- } else {
- $cleaned[ $node->node ] = $node;
- }
- }
- }
- }
- return $cleaned;
- }
- /**
- * Detect if the current layout has previously drafted changes.
- *
- * @since 2.0
- * @return bool
- */
- static public function layout_has_drafted_changes() {
- $post_id = FLBuilderModel::get_post_id();
- $published = serialize( self::get_layout_data( 'published', $post_id ) );
- $draft = serialize( self::get_layout_data( 'draft', $post_id ) );
- if ( $published != $draft ) {
- return true;
- }
- return false;
- }
- /**
- * Get the builder settings for a layout.
- *
- * @since 1.7
- * @param string $status Either published or draft.
- * @param int $post_id The ID of the post to get settings for.
- * @return object
- */
- static public function get_layout_settings( $status = null, $post_id = null ) {
- $status = ! $status ? self::get_node_status() : $status;
- $post_id = ! $post_id ? self::get_post_id() : $post_id;
- $key = 'published' == $status ? '_fl_builder_data_settings' : '_fl_builder_draft_settings';
- $settings = get_metadata( 'post', $post_id, $key, true );
- $defaults = self::get_settings_form_defaults( 'layout' );
- if ( ! $settings ) {
- $settings = new StdClass();
- }
- $settings = (object) array_merge( (array) $defaults, (array) $settings );
- return apply_filters( 'fl_builder_layout_settings', $settings, $status, $post_id );
- }
- /**
- * Updates the layout settings for a post.
- *
- * @since 1.7
- * @param array $settings The new layout settings.
- * @param string $status Either published or draft.
- * @param int $post_id The ID of the post to update.
- * @return object
- */
- static public function update_layout_settings( $settings = array(), $status = null, $post_id = null ) {
- $status = ! $status ? self::get_node_status() : $status;
- $post_id = ! $post_id ? self::get_post_id() : $post_id;
- $key = 'published' == $status ? '_fl_builder_data_settings' : '_fl_builder_draft_settings';
- $raw_settings = get_metadata( 'post', $post_id, $key );
- $old_settings = self::get_layout_settings( $status, $post_id );
- $new_settings = (object) array_merge( (array) $old_settings, (array) $settings );
- if ( 0 === count( $raw_settings ) ) {
- add_metadata( 'post', $post_id, $key, self::slash_settings( $new_settings ) );
- } else {
- update_metadata( 'post', $post_id, $key, self::slash_settings( $new_settings ) );
- }
- return $new_settings;
- }
- /**
- * Called via AJAX to save the layout settings.
- *
- * @since 1.7
- * @param array $settings The new layout settings.
- * @param string $status Either published or draft.
- * @param int $post_id The ID of the post to update.
- * @return object
- */
- static public function save_layout_settings( $settings = array(), $status = null, $post_id = null ) {
- return self::update_layout_settings( $settings, $status, $post_id );
- }
- /**
- * Delete the layout settings for a post.
- *
- * @since 1.7
- * @param string $status Either published or draft.
- * @param int $post_id The ID of a post whose settings to delete.
- * @return void
- */
- static public function delete_layout_settings( $status = null, $post_id = null ) {
- $status = ! $status ? self::get_node_status() : $status;
- $post_id = ! $post_id ? self::get_post_id() : $post_id;
- $key = 'published' == $status ? '_fl_builder_data_settings' : '_fl_builder_draft_settings';
- update_metadata( 'post', $post_id, $key, array() );
- }
- /**
- * Merge two sets of layout settings together.
- *
- * @since 1.7
- * @param object $settings The layout settings to merge into.
- * @param object $merge_settings The layout settings to merge.
- * @return object
- */
- static public function merge_layout_settings( $settings, $merge_settings ) {
- $keys = array( 'css', 'js' );
- foreach ( $keys as $key ) {
- if ( empty( $merge_settings->{$key} ) ) {
- continue;
- } elseif ( strstr( $settings->{$key}, $merge_settings->{$key} ) ) {
- continue;
- } else {
- if ( ! empty( $settings->{$key} ) ) {
- $settings->{$key} .= "\n";
- }
- $settings->{$key} .= $merge_settings->{$key};
- }
- }
- return $settings;
- }
- /**
- * Clears a draft layout and saves a new draft using
- * the currently published layout data.
- *
- * @since 1.0
- * @return void
- */
- static public function clear_draft_layout() {
- $post_id = self::get_post_id();
- $data = self::get_layout_data( 'published', $post_id );
- $settings = self::get_layout_settings( 'published', $post_id );
- // Delete the old draft layout.
- self::delete_layout_data( 'draft' );
- // Save the new draft layout.
- self::update_layout_data( $data, 'draft', $post_id );
- // Save the new draft layout settings.
- self::update_layout_settings( $settings, 'draft', $post_id );
- // Clear the asset cache.
- self::delete_all_asset_cache( $post_id );
- }
- /**
- * Saves layout data when a user chooses to publish.
- *
- * @since 1.0
- * @param bool $publish Whether to publish the parent post or not.
- * @return void
- */
- static public function save_layout( $publish = true ) {
- $editor_content = FLBuilder::render_editor_content();
- $post_id = self::get_post_id();
- $data = self::get_layout_data( 'draft', $post_id );
- $settings = self::get_layout_settings( 'draft', $post_id );
- /**
- * This action allows you to hook into before the data is saved for a layout.
- * @see fl_builder_before_save_layout
- * @link https://kb.wpbeaverbuilder.com/article/116-plugin-action-reference
- */
- do_action( 'fl_builder_before_save_layout', $post_id, $publish, $data, $settings );
- // Delete the old published layout.
- self::delete_layout_data( 'published', $post_id );
- self::delete_layout_settings( 'published', $post_id );
- // Save the new published layout.
- self::update_layout_data( $data, 'published', $post_id );
- self::update_layout_settings( $settings, 'published', $post_id );
- // Clear the asset cache.
- self::delete_all_asset_cache( $post_id );
- self::delete_node_template_asset_cache( $post_id );
- // Enable the builder to take over the post content.
- self::enable();
- // Get the post status.
- $post_status = get_post_status( $post_id );
- // Publish the post?
- if ( $publish ) {
- $is_draft = strstr( $post_status, 'draft' );
- $is_pending = strstr( $post_status, 'pending' );
- if ( current_user_can( 'publish_posts' ) ) {
- $post_status = $is_draft || $is_pending ? 'publish' : $post_status;
- } elseif ( $is_draft ) {
- $post_status = 'pending';
- }
- }
- // Update the post with stripped down content.
- wp_update_post(array(
- 'ID' => self::get_post_id(),
- 'post_status' => $post_status,
- 'post_content' => $editor_content,
- ));
- // Rerender the assets for this layout.
- FLBuilder::render_assets();
- /**
- * This action allows you to hook into after the data is saved for a layout.
- * @see fl_builder_after_save_layout
- * @link https://kb.wpbeaverbuilder.com/article/116-plugin-action-reference
- */
- do_action( 'fl_builder_after_save_layout', $post_id, $publish, $data, $settings );
- }
- /**
- * Publishes the current builder layout only if the parent post
- * is still a draft. The layout will be published but the parent
- * post will remain a draft so the post can be scheduled and the
- * layout can be viewed while the builder is not active. If the
- * parent post is already published, nothing happens.
- *
- * @since 1.6.1
- * @return void
- */
- static public function save_draft() {
- $post_id = self::get_post_id();
- $post_status = get_post_status( $post_id );
- if ( strstr( $post_status, 'draft' ) ) {
- self::save_layout( false );
- }
- do_action( 'fl_builder_after_save_draft', $post_id, $post_status );
- }
- /**
- * Duplicates a layout for WPML when the copy from original
- * button has been clicked.
- *
- * @since 1.1.7
- * @param int $original_post_id
- * @param int $new_post_id
- * @return array
- */
- static public function duplicate_wpml_layout( $original_post_id = null, $new_post_id = null ) {
- $post_data = self::get_post_data();
- $original_post_id = isset( $post_data['original_post_id'] ) ? $post_data['original_post_id'] : $original_post_id;
- $new_post_id = isset( $post_data['post_id'] ) ? $post_data['post_id'] : $new_post_id;
- $enabled = get_post_meta( $original_post_id, '_fl_builder_enabled', true );
- $published = self::get_layout_data( 'published', $original_post_id );
- $draft = self::get_layout_data( 'draft', $original_post_id );
- $response = array(
- 'enabled' => false,
- 'has_layout' => false,
- );
- if ( ! empty( $enabled ) ) {
- update_post_meta( $new_post_id, '_fl_builder_enabled', true );
- $response['enabled'] = true;
- }
- if ( ! empty( $published ) ) {
- self::update_layout_data( $published, 'published', $new_post_id );
- $response['has_layout'] = true;
- }
- if ( ! empty( $draft ) ) {
- self::update_layout_data( $draft, 'draft', $new_post_id );
- $response['has_layout'] = true;
- }
- return $response;
- }
- /**
- * Returns the type of templates that are enabled.
- *
- * @since 1.1.3
- * @return string
- */
- static public function get_enabled_templates() {
- $value = self::get_admin_settings_option( '_fl_builder_enabled_templates', true );
- return ! $value ? 'enabled' : $value;
- }
- /**
- * Checks to see if the current post is a user template.
- *
- * @since 1.6.3
- * @param string $type The type of user template to check for.
- * @return bool
- */
- static public function is_post_user_template( $type = null ) {
- $post = FLBuilderModel::get_post();
- if ( ! $post ) {
- return false;
- } elseif ( 'fl-builder-template' == $post->post_type ) {
- if ( null === $type ) {
- return true;
- } else {
- $saved_type = self::get_user_template_type( $post->ID );
- if ( $saved_type == $type ) {
- return true;
- }
- }
- }
- return false;
- }
- /**
- * Saves a user defined template via AJAX.
- *
- * @since 1.1.3
- * @return void
- */
- static public function save_user_template( $settings = array() ) {
- // Save the user template post.
- $post_id = wp_insert_post(array(
- 'post_title' => $settings['name'],
- 'post_type' => 'fl-builder-template',
- 'post_status' => 'publish',
- 'ping_status' => 'closed',
- 'comment_status' => 'closed',
- ));
- // Set the template type.
- wp_set_post_terms( $post_id, 'layout', 'fl-builder-template-type' );
- // Add category
- $cat = isset( $settings['category'] ) ? $settings['category'] : '';
- $cat_added = '';
- if ( __( 'Uncategorized', 'fl-builder' ) !== $cat && 'uncategorized' !== $cat ) {
- $cat_added = wp_set_object_terms( $post_id, $cat, 'fl-builder-template-category' );
- }
- // Get the layout data and settings to copy.
- $data = self::get_layout_data();
- $layout_settings = self::get_layout_settings();
- // Generate new node ids.
- $data = self::generate_new_node_ids( $data );
- // Save the template layout data and settings.
- self::update_layout_data( $data, 'published', $post_id );
- self::update_layout_settings( $layout_settings, 'published', $post_id );
- // Enable the builder for this template.
- update_post_meta( $post_id, '_fl_builder_enabled', true );
- // Allow extensions to hook into saving a user template.
- do_action( 'fl_builder_after_save_user_template', $post_id );
- $response = array(
- 'name' => $settings['name'],
- 'id' => get_post_meta( $post_id, '_fl_builder_template_id', true ),
- 'postId' => $post_id,
- 'image' => FL_BUILDER_URL . 'img/templates/blank.jpg',
- 'kind' => 'template',
- 'content' => 'layout',
- 'type' => 'user',
- 'isGlobal' => false,
- 'link' => add_query_arg( 'fl_builder', '', get_permalink( $post_id ) ),
- 'category' => array(),
- );
- if ( is_array( $cat_added ) && ! empty( $cat_added ) ) {
- $term = get_term( $cat_added[0] );
- $response['category'][ $term->slug ] = $term->name;
- } else {
- $response['category']['uncategorized'] = __( 'Uncategorized', 'fl-builder' );
- }
- return $response;
- }
- /**
- * Returns data for all user defined templates.
- *
- * @since 1.1.3
- * @since 1.5.7 Added support for template categories.
- * @param string $type The type of user template to return.
- * @return array
- */
- static public function get_user_templates( $type = 'layout' ) {
- $categorized = array(
- 'uncategorized' => array(
- 'name' => _x( 'Uncategorized', 'Default user template category.', 'fl-builder' ),
- 'templates' => array(),
- ),
- );
- $posts = get_posts( array(
- 'post_type' => 'fl-builder-template',
- 'orderby' => 'menu_order title',
- 'order' => 'ASC',
- 'posts_per_page' => '-1',
- 'tax_query' => array(
- array(
- 'taxonomy' => 'fl-builder-template-type',
- 'field' => 'slug',
- 'terms' => $type,
- ),
- ),
- ) );
- $templates = array();
- // Loop through templates posts and build the templates array.
- foreach ( $posts as $post ) {
- if ( has_post_thumbnail( $post->ID ) ) {
- $image_data = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'medium_large' );
- $image = $image_data[0];
- } else {
- $image = FL_BUILDER_URL . 'img/templates/blank.jpg';
- }
- $templates[] = array(
- 'id' => get_post_meta( $post->ID, '_fl_builder_template_id', true ),
- 'postId' => $post->ID,
- 'name' => $post->post_title,
- 'image' => $image,
- 'kind' => 'template',
- 'type' => 'user',
- 'content' => FLBuilderModel::get_user_template_type( $post->ID ),
- 'isGlobal' => FLBuilderModel::is_post_global_node_template( $post->ID ),
- 'link' => add_query_arg( 'fl_builder', '', get_permalink( $post->ID ) ),
- 'category' => array(),
- );
- }
- // Loop through templates and build the categorized array.
- foreach ( $templates as $i => $template ) {
- $cats = wp_get_post_terms( $template['postId'], 'fl-builder-template-category' );
- if ( 0 === count( $cats ) || is_wp_error( $cats ) ) {
- $template['category'] = array(
- 'uncategorized' => __( 'Uncategorized', 'fl-builder' ),
- );
- $categorized['uncategorized']['templates'][] = $template;
- } else {
- foreach ( $cats as $cat ) {
- $template['category'][ $cat->slug ] = $cat->name;
- }
- foreach ( $cats as $cat ) {
- if ( ! isset( $categorized[ $cat->slug ] ) ) {
- $categorized[ $cat->slug ] = array(
- 'name' => $cat->name,
- 'templates' => array(),
- );
- }
- $categorized[ $cat->slug ]['templates'][] = $template;
- }
- }
- $templates[ $i ] = $template;
- }
- // Unset the uncategorized cat if no templates.
- if ( 0 === count( $categorized['uncategorized']['templates'] ) ) {
- unset( $categorized['uncategorized'] );
- }
- // sort the categories.
- asort( $categorized );
- return array(
- 'templates' => $templates,
- 'categorized' => $categorized,
- );
- }
- /**
- * Returns the template type for a user template.
- *
- * @since 1.6.3
- * @param int $template_id The post ID of the template.
- * @return string
- */
- static public function get_user_template_type( $template_id = null ) {
- if ( $template_id && isset( self::$node_template_types[ $template_id ] ) ) {
- return self::$node_template_types[ $template_id ];
- }
- $post = $template_id ? get_post( $template_id ) : FLBuilderModel::get_post();
- if ( ! is_object( $post ) || 'fl-builder-template' != $post->post_type ) {
- return '';
- } else {
- $terms = wp_get_post_terms( $post->ID, 'fl-builder-template-type' );
- $type = ( 0 === count( $terms ) ) ? 'layout' : $terms[0]->slug;
- self::$node_template_types[ $template_id ] = $type;
- return $type;
- }
- }
- /**
- * Delete a user defined template.
- *
- * @since 1.1.3
- * @param int $template_id The post ID of the template to delete.
- * @return void
- */
- static public function delete_user_template( $template_id = null ) {
- if ( isset( $template_id ) ) {
- wp_delete_post( $template_id, true );
- }
- }
- /**
- * Apply a user defined template to the current layout.
- *
- * @since 1.1.3
- * @param int|object $template The post ID of the template to apply or a template data object.
- * @param bool $append Whether to append the new template or replacing the existing layout.
- * @return array
- */
- static public function apply_user_template( $template = null, $append = false ) {
- if ( $template ) {
- // Delete existing nodes and settings?
- if ( ! $append ) {
- self::delete_layout_data( 'draft' );
- self::delete_layout_settings( 'draft' );
- }
- // Insert new nodes if this is not a blank template.
- if ( 'blank' != $template ) {
- // Get the template data if $template is not an object.
- if ( ! is_object( $template ) ) {
- $template_id = $template;
- $template = new StdClass();
- $template->nodes = self::get_layout_data( 'published', $template_id );
- $template->settings = self::get_layout_settings( 'published', $template_id );
- }
- // Get new ids for the template nodes.
- $template->nodes = self::generate_new_node_ids( $template->nodes );
- // Get the existing layout data and settings.
- $layout_data = self::get_layout_data();
- $layout_settings = self::get_layout_settings();
- // Reposition rows if we are appending.
- if ( $append ) {
- $row_position = self::next_node_position( 'row' );
- foreach ( $template->nodes as $node_id => $node ) {
- if ( 'row' == $node->type ) {
- $template->nodes[ $node_id ]->position += $row_position;
- }
- }
- }
- // Merge the layout data and settings.
- $data = array_merge( $layout_data, $template->nodes );
- $settings = self::merge_layout_settings( $layout_settings, $template->settings );
- // Update the layout data and settings.
- self::update_layout_data( $data );
- self::update_layout_settings( $settings );
- // Delete old asset cache.
- self::delete_asset_cache();
- }
- }
- // Return the layout.
- return array(
- 'layout_css' => isset( $settings ) ? $settings->css : null,
- 'layout' => FLBuilderAJAXLayout::render(),
- 'config' => FLBuilderUISettingsForms::get_node_js_config(),
- );
- }
- /**
- * Returns true if the node templates UI is enabled, false if not.
- *
- * @since 1.6.3
- * @return bool
- */
- static public function node_templates_enabled() {
- $enabled_templates = self::get_enabled_templates();
- if ( true === FL_BUILDER_LITE ) {
- return false;
- }
- if ( 'core' == $enabled_templates || 'disabled' == $enabled_templates ) {
- return false;
- }
- return true;
- }
- /**
- * Checks to see if the current post is a node template.
- *
- * @since 1.6.3
- * @param int $post_id If supplied, this post will be checked instead.
- * @return bool
- */
- static public function is_post_node_template( $post_id = false ) {
- $post_id = $post_id ? $post_id : self::get_post_id();
- $post = get_post( $post_id );
- if ( ! $post ) {
- return false;
- } elseif ( 'fl-builder-template' == $post->post_type ) {
- $saved_type = self::get_user_template_type( $post->ID );
- if ( in_array( $saved_type, array( 'row', 'column', 'module' ) ) ) {
- return true;
- }
- }
- return false;
- }
- /**
- * Checks to see if the current post is a global node template.
- *
- * @since 1.6.3
- * @param int $post_id If supplied, this post will be checked instead.
- * @return bool
- */
- static public function is_post_global_node_template( $post_id = false ) {
- $post_id = $post_id ? $post_id : self::get_post_id();
- if ( ! self::is_post_node_template( $post_id ) ) {
- return false;
- }
- $global = get_post_meta( $post_id, '_fl_builder_template_global', true );
- if ( ! $global ) {
- return false;
- }
- return true;
- }
- /**
- * Checks to see if a node is a global node.
- *
- * @since 1.6.3
- * @param object $node The node object to check.
- * @return bool|int
- */
- static public function is_node_global( $node ) {
- if ( ! isset( $node->template_id ) ) {
- return false;
- }
- return self::get_node_template_post_id( $node->template_id );
- }
- /**
- * Check the visibility settings that has been sets from any type of node (rows/columns/modules)
- * This will be applied ONLY when the builder is not active.
- *
- * @param object $node The type of object to check
- * @return bool
- */
- static public function is_node_visible( $node ) {
- global $wp_the_query;
- $is_visible = true;
- if ( isset( $node->settings->visibility_display ) && ('' != $node->settings->visibility_display) ) {
- // For logged out users
- if ( 'logged_out' == $node->settings->visibility_display && ! is_user_logged_in() ) {
- $is_visible = true;
- } elseif ( 'logged_in' == $node->settings->visibility_display && is_user_logged_in() ) {
- $is_visible = true;
- // User capability setting
- if ( isset( $node->settings->visibility_user_capability ) && ! empty( $node->settings->visibility_user_capability ) ) {
- if ( self::current_user_has_capability( trim( $node->settings->visibility_user_capability ) ) ) {
- $is_visible = true;
- } else {
- $is_visible = false;
- }
- }
- } elseif ( 0 == $node->settings->visibility_display ) {
- $is_visible = false;
- } else {
- $is_visible = false;
- }
- }
- return apply_filters( 'fl_builder_is_node_visible', $is_visible, $node );
- }
- /**
- * Checks if a node has visibility rules or not.
- *
- * @param object $node
- * @return bool
- */
- static public function node_has_visibility_rules( $node ) {
- return isset( $node->settings->visibility_display ) && ( '' !== $node->settings->visibility_display );
- }
- /**
- * Checks to see if a node is the root node of a global template.
- *
- * @since 1.6.3
- * @param object $node The node object to check.
- * @return bool|int
- */
- static public function is_node_template_root( $node ) {
- return self::is_node_global( $node ) && isset( $node->template_root_node );
- }
- /**
- * Get an array of node template info.
- *
- * @since 1.6.3
- * @param string $type The type of node template to get.
- * @return array
- */
- static public function get_node_templates( $type = '' ) {
- $posts = get_posts( array(
- 'post_type' => 'fl-builder-template',
- 'orderby' => 'title',
- 'order' => 'ASC',
- 'posts_per_page' => '-1',
- 'tax_query' => array(
- array(
- 'taxonomy' => 'fl-builder-template-type',
- 'field' => 'slug',
- 'terms' => $type,
- ),
- ),
- ) );
- $templates = array();
- foreach ( $posts as $post ) {
- $templates[] = array(
- 'id' => get_post_meta( $post->ID, '_fl_builder_template_id', true ),
- 'global' => get_post_meta( $post->ID, '_fl_builder_template_global', true ),
- 'link' => add_query_arg( 'fl_builder', '', get_permalink( $post->ID ) ),
- 'name' => $post->post_title,
- );
- }
- return $templates;
- }
- /**
- * Returns the root node for a node template.
- *
- * @since 1.6.3
- * @param string $type The type of node template.
- * @param array $nodes The node template data.
- * @return object
- */
- static public function get_node_template_root( $type = '', $nodes = array() ) {
- if ( '' != $type ) {
- $nodes = count( $nodes ) > 0 ? $nodes : self::get_nodes( $type );
- }
- foreach ( $nodes as $node ) {
- if ( $type == $node->type ) {
- // Root parent for column template should be null.
- if ( 'column' == $type && $node->parent ) {
- continue;
- }
- return $node;
- }
- }
- return false;
- }
- /**
- * Uses a node template ID to retrieve its post ID.
- *
- * @since 1.6.3
- * @param string $template_id The node template ID as stored in the template's post meta.
- * @return int
- */
- static public function get_node_template_post_id( $template_id ) {
- if ( isset( self::$node_template_post_ids[ $template_id ] ) ) {
- return self::$node_template_post_ids[ $template_id ];
- } else {
- $posts = get_posts( array(
- 'post_type' => 'fl-builder-template',
- 'post_status' => array( 'any', 'trash' ),
- 'posts_per_page' => '-1',
- 'post_status' => 'any',
- 'meta_key' => '_fl_builder_template_id',
- 'meta_value' => $template_id,
- ) );
- if ( 0 === count( $posts ) ) {
- return false;
- }
- $post_id = apply_filters( 'fl_builder_node_template_post_id', $posts[0]->ID );
- self::$node_template_post_ids[ $template_id ] = $post_id;
- return $post_id;
- }
- }
- /**
- * Returns the edit URL for a node template.
- *
- * @since 1.6.3
- * @param string $template_id The node template ID as stored in the template's post meta.
- * @return string
- */
- static public function get_node_template_edit_url( $template_id ) {
- return self::get_edit_url( self::get_node_template_post_id( $template_id ) );
- }
- /**
- * Returns an array of posts that have the global node template
- * with the specified ID.
- *
- * @since 1.6.3
- * @param int $post_id The post ID of the global node template.
- * @return array
- */
- static public function get_posts_with_global_node_template( $post_id = false ) {
- $posts = array();
- if ( self::is_post_global_node_template( $post_id ) ) {
- $template_id = get_post_meta( $post_id, '_fl_builder_template_id', true );
- $query = new WP_Query( array(
- 'meta_query' => array(
- 'relation' => 'OR',
- array(
- 'key' => '_fl_builder_data',
- 'value' => $template_id,
- 'compare' => 'LIKE',
- ),
- array(
- 'key' => '_fl_builder_draft',
- 'value' => $template_id,
- 'compare' => 'LIKE',
- )
- ),
- 'post_type' => 'any',
- 'post_status' => 'any',
- 'post__not_in' => array( $post_id ),
- ) );
- $posts = $query->posts;
- }
- return $posts;
- }
- /**
- * Saves a node template.
- *
- * @since 1.6.3
- * @param string $template_node_id The ID of the node to save as a template.
- * @param string $settings The settings for this template.
- * @return void
- */
- static public function save_node_template( $template_node_id, $settings ) {
- $root_node = self::get_node( $template_node_id );
- $nodes = self::get_nested_nodes( $template_node_id );
- $template_id = self::generate_node_id();
- $original_parent = $root_node->parent;
- $original_position = $root_node->position;
- // Save the node template post.
- $post_id = wp_insert_post( array(
- 'post_title' => $settings['name'],
- 'post_type' => 'fl-builder-template',
- 'post_status' => 'publish',
- 'ping_status' => 'closed',
- 'comment_status' => 'closed',
- ) );
- // Set the template type.
- wp_set_post_terms( $post_id, $root_node->type, 'fl-builder-template-type' );
- // Reset the root node's position.
- $root_node->position = 0;
- // Remove root parent for column template.
- if ( 'column' == $root_node->type ) {
- $root_node->parent = null;
- $root_node->settings->size = 100;
- }
- // Add the root node to the nodes array.
- $nodes[ $root_node->node ] = $root_node;
- // Generate new node ids.
- $nodes = self::generate_new_node_ids( $nodes );
- // Get the root node from the template data since its ID changed.
- $root_node = self::get_node_template_root( $root_node->type, $nodes );
- // Add the template ID and template node ID for global templates.
- if ( $settings['global'] ) {
- foreach ( $nodes as $node_id => $node ) {
- $nodes[ $node_id ]->template_id = $template_id;
- $nodes[ $node_id ]->template_node_id = $node_id;
- if ( $node_id == $root_node->node ) {
- $nodes[ $node_id ]->template_root_node = true;
- } elseif ( isset( $nodes[ $node_id ]->template_root_node ) ) {
- unset( $nodes[ $node_id ]->template_root_node );
- }
- }
- } else {
- foreach ( $nodes as $node_id => $node ) {
- if ( isset( $nodes[ $node_id ]->template_id ) ) {
- unset( $nodes[ $node_id ]->template_id );
- }
- if ( isset( $nodes[ $node_id ]->template_node_id ) ) {
- unset( $nodes[ $node_id ]->template_node_id );
- }
- if ( isset( $nodes[ $node_id ]->template_root_node ) ) {
- unset( $nodes[ $node_id ]->template_root_node );
- }
- }
- }
- // Save the template layout data.
- self::update_layout_data( $nodes, 'published', $post_id );
- self::update_layout_data( $nodes, 'draft', $post_id );
- // Enable the builder for this template.
- update_post_meta( $post_id, '_fl_builder_enabled', true );
- // Add the template ID post meta. We use a custom ID for node
- // templates in case templates are imported since their WordPress
- // IDs will change, breaking global templates.
- update_post_meta( $post_id, '_fl_builder_template_id', $template_id );
- // Add the template global flag post meta.
- update_post_meta( $post_id, '_fl_builder_template_global', $settings['global'] );
- // Delete the existing node and apply the template for global templates.
- if ( $settings['global'] ) {
- // Delete the existing node.
- self::delete_node( $template_node_id );
- // Apply the global template.
- $root_node = self::apply_node_template( $template_id, $original_parent, $original_position );
- }
- // Return an array of template settings.
- return array(
- 'id' => $template_id,
- 'global' => $settings['global'] ? true : false,
- 'link' => add_query_arg( 'fl_builder', '', get_permalink( $post_id ) ),
- 'name' => $settings['name'],
- 'type' => $root_node->type,
- 'layout' => $settings['global'] ? FLBuilderAJAXLayout::render( $root_node->node, $template_node_id ) : null,
- 'config' => $settings['global'] ? FLBuilderUISettingsForms::get_node_js_config() : null,
- 'postID' => $post_id,
- );
- }
- /**
- * Sets the default type for a node template when created in wp-admin.
- *
- * @since 1.6.3
- * @param int $post_ID The post ID for the template.
- * @param object $post The post object for the template.
- * @param bool $update Whether this is a new post or an update.
- * @return void
- */
- static public function set_node_template_default_type( $post_id, $post, $update ) {
- global $pagenow;
- if ( 'admin.php' == $pagenow && isset( $_GET['import'] ) ) {
- return;
- }
- $post_data = self::get_post_data();
- if ( $update || 'fl-builder-template' != $post->post_type ) {
- return;
- }
- if ( isset( $post_data['fl_action'] ) && 'duplicate_post' == $post_data['fl_action'] ) {
- return;
- }
- $type = wp_get_post_terms( $post_id, 'fl-builder-template-type' );
- if ( 0 === count( $type ) ) {
- wp_set_post_terms( $post_id, 'layout', 'fl-builder-template-type' );
- }
- }
- /**
- * Deletes a node template via AJAX.
- *
- * @since 1.6.3
- * @param string $template_id The ID of node template to delete.
- * @return void
- */
- static public function delete_node_template( $template_id ) {
- // Make sure we have a template ID.
- if ( ! isset( $template_id ) ) {
- return;
- }
- // Get the post ID for the template.
- $template_post_id = self::get_node_template_post_id( $template_id );
- // Bail if we don't have a post ID.
- if ( ! $template_post_id ) {
- return;
- }
- // Unlink if this is a global template.
- self::unlink_global_node_template_from_all_posts( $template_post_id );
- // Delete the template post.
- wp_delete_post( $template_post_id, true );
- }
- /**
- * Unlinks all instances of a global node template in all posts.
- *
- * @since 1.6.3
- * @param int $template_post_id The post ID of the template to unlink.
- * @return void
- */
- static public function unlink_global_node_template_from_all_posts( $template_post_id ) {
- if ( self::is_post_global_node_template( $template_post_id ) ) {
- $posts = self::get_posts_with_global_node_template( $template_post_id );
- $template_id = get_post_meta( $template_post_id, '_fl_builder_template_id', true );
- foreach ( $posts as $post ) {
- self::unlink_global_node_template_from_post( 'published', $post->ID, $template_post_id, $template_id );
- self::unlink_global_node_template_from_post( 'draft', $post->ID, $template_post_id, $template_id );
- self::delete_all_asset_cache( $post->ID );
- }
- }
- }
- /**
- * Unlinks all instances of a global node template from a post's
- * layout data with the specified status. Since only the root node
- * of a global template is saved to a posts layout data, the child
- * nodes will be saved to the post when the global template is unlinked.
- *
- * @since 1.6.3
- * @param string $status The status of the layout data. Either draft or published.
- * @param int $post_id The ID of the post to unlink from.
- * @param string $template_post_id The post ID of the template to unlink from the layout data.
- * @param string $template_id The ID of the template to unlink from the layout data.
- * @return void
- */
- static public function unlink_global_node_template_from_post( $status, $post_id, $template_post_id, $template_id ) {
- $template_data = self::get_layout_data( $status, $template_post_id );
- $layout_data = self::get_layout_data( $status, $post_id );
- $update = false;
- // Loop through the layout data.
- foreach ( $layout_data as $node_id => $node ) {
- // Check to see if this is the global template node to unlink.
- if ( isset( $node->template_id ) && $node->template_id == $template_id ) {
- // Generate new node ids for the template data.
- $new_data = self::generate_new_node_ids( $template_data );
- // Get the root node from the template data.
- $root_node = self::get_node_template_root( $node->type, $new_data );
- // Remove the root node from the template data since it's already in the layout.
- unset( $new_data[ $root_node->node ] );
- // Update the settings for the root node in this layout.
- $layout_data[ $node_id ]->settings = $root_node->settings;
- // Update children with the new parent node ID.
- foreach ( $new_data as $i => $n ) {
- if ( $n->parent == $root_node->node ) {
- $new_data[ $i ]->parent = $node->node;
- }
- }
- // Add the template data to the layout data.
- $layout_data = array_merge( $layout_data, $new_data );
- // Set the update flag.
- $update = true;
- }
- }
- // Only update if we need to.
- if ( $update ) {
- // Remove template info from the layout data.
- foreach ( $layout_data as $node_id => $node ) {
- unset( $layout_data[ $node_id ]->template_id );
- unset( $layout_data[ $node_id ]->template_node_id );
- unset( $layout_data[ $node_id ]->template_root_node );
- }
- // Update the layout data.
- self::update_layout_data( $layout_data, $status, $post_id );
- }
- }
- /**
- * Deletes all instances of a global node template from all posts.
- *
- * @since 1.6.3
- * @param int $template_post_id The post ID of the template to delete.
- * @return void
- */
- static public function delete_global_node_template_from_all_posts( $template_post_id ) {
- if ( self::is_post_global_node_template( $template_post_id ) ) {
- $posts = self::get_posts_with_global_node_template( $template_post_id );
- $template_id = get_post_meta( $template_post_id, '_fl_builder_template_id', true );
- foreach ( $posts as $post ) {
- self::delete_global_node_template_from_post( 'published', $post->ID, $template_id );
- self::delete_global_node_template_from_post( 'draft', $post->ID, $template_id );
- self::delete_all_asset_cache( $post->ID );
- }
- }
- }
- /**
- * Deletes all instances of a global node template from a post's
- * layout data with the specified status.
- *
- * @since 1.6.3
- * @param string $status The status of the layout data. Either draft or published.
- * @param int $post_id The ID of the post to delete from.
- * @param string $template_id The ID of the template to delete from the layout data.
- * @return void
- */
- static public function delete_global_node_template_from_post( $status, $post_id, $template_id ) {
- $layout_data = self::get_layout_data( $status, $post_id );
- $update = false;
- // Loop through the nodes.
- foreach ( $layout_data as $node_id => $node ) {
- $siblings = array();
- $position = 0;
- // Check to see if this is the global template node to delete.
- if ( isset( $node->template_id ) && $node->template_id == $template_id ) {
- // Unset this node in the layout data.
- unset( $layout_data[ $node_id ] );
- // Find sibiling nodes to update their position.
- foreach ( $layout_data as $i => $n ) {
- if ( $n->parent == $node->parent ) {
- $siblings[ $i ] = $n;
- }
- }
- // Sort the sibiling nodes by position.
- uasort( $siblings, array( 'FLBuilderModel', 'order_nodes' ) );
- // Update sibiling node positions.
- foreach ( $siblings as $i => $n ) {
- $layout_data[ $i ]->position = $position;
- $position++;
- }
- // Set the update flag.
- $update = true;
- }
- }
- // Only update if we need to.
- if ( $update ) {
- self::update_layout_data( $layout_data, $status, $post_id );
- }
- }
- /**
- * Applies a node template to the current layout.
- *
- * @since 1.6.3
- * @param int $template_id The node template ID.
- * @param string $parent_id The new parent node ID for the template.
- * @param int $position The position of the template within the layout.
- * @param object $template Optional. Template data to use instead of pulling it with the template ID.
- * @return void
- */
- static public function apply_node_template( $template_id = null, $parent_id = null, $position = 0, $template = null ) {
- $parent = ( 0 == $parent_id ) ? null : self::get_node( $parent_id );
- $template_post_id = self::get_node_template_post_id( $template_id );
- $is_col_template = false;
- // Allow extensions to hook into applying a node template.
- $override = apply_filters( 'fl_builder_override_apply_node_template', false, array(
- 'template_id' => $template_id,
- 'parent_id' => $parent_id,
- 'position' => $position,
- 'template' => $template,
- 'template_post_id' => $template_post_id,
- ) );
- // Return if we got an override from the filter.
- if ( $override ) {
- return $override;
- }
- // Get the template data from $template if we have it.
- if ( is_object( $template ) ) {
- $template_data = $template->nodes;
- $template_settings = $template->settings;
- $type = $template->type;
- $global = $template->global;
- } else {
- $template_data = self::get_layout_data( 'published', $template_post_id );
- $template_settings = self::get_layout_settings( 'published', $template_post_id );
- $type = self::get_user_template_type( $template_post_id );
- $global = get_post_meta( $template_post_id, '_fl_builder_template_global', true );
- }
- // Generate new node ids.
- $template_data = self::generate_new_node_ids( $template_data );
- // Get the root node from the template data.
- $root_node = self::get_node_template_root( $type, $template_data );
- // Handle module and column templates.
- if ( 'module' == $root_node->type || 'column' == $root_node->type ) {
- // Add a new parent for module or column node templates if needed.
- if ( ! $parent || 'row' == $parent->type || 'column-group' == $parent->type ) {
- if ( 'module' == $root_node->type ) {
- $parent_id = self::add_module_parent( $parent_id, $position );
- $position = null;
- } elseif ( 'column' == $root_node->type ) {
- $parent_id = self::add_col_parent( $parent_id, $position );
- $is_col_template = self::is_node_global( $root_node );
- }
- $parent = self::get_node( $parent_id );
- }
- // Set the node's template data if the parent is a global node.
- if ( self::is_node_global( $parent ) && ! $is_col_template ) {
- $template_data[ $root_node->node ]->template_id = $parent->template_id;
- $template_data[ $root_node->node ]->template_node_id = $root_node->node;
- unset( $template_data[ $root_node->node ]->template_root_node );
- $global = true;
- }
- }
- // Update the root node's parent.
- $template_data[ $root_node->node ]->parent = ! $parent_id ? null : $parent_id;
- // Get the layout data and settings.
- $layout_data = self::get_layout_data( 'draft' );
- $layout_settings = self::get_layout_settings( 'draft' );
- // Only merge the root node for global templates.
- if ( $global ) {
- $layout_data[ $root_node->node ] = $template_data[ $root_node->node ];
- } else {
- // Merge template data.
- foreach ( $template_data as $node_id => $node ) {
- unset( $template_data[ $node_id ]->template_id );
- unset( $template_data[ $node_id ]->template_node_id );
- unset( $template_data[ $node_id ]->template_root_node );
- }
- $layout_data = array_merge( $layout_data, $template_data );
- // Merge template settings.
- $layout_settings = self::merge_layout_settings( $layout_settings, $template_settings );
- }
- // Update the layout data and settings.
- self::update_layout_data( $layout_data );
- self::update_layout_settings( $layout_settings );
- // Reorder the main template node.
- if ( null !== $position ) {
- self::reorder_node( $root_node->node, $position );
- }
- // Re-size column widths
- if ( 'column' == $root_node->type && 'column-group' == $parent->type ) {
- self::reset_col_widths( $parent_id );
- }
- // Delete old asset cache.
- self::delete_asset_cache();
- // Return the root node.
- if ( 'module' == $root_node->type ) {
- return self::get_module( $root_node->node );
- } else {
- return $root_node;
- }
- }
- /**
- * Registers a template data file with the builder.
- *
- * @since 1.8
- * @param string|array $path The directory path to the template data file.
- * @param array $meta The collection information for this template file.
- * @return void
- */
- static public function register_templates( $path = false, $args = array() ) {
- // Check if the file exists if path is a string.
- if ( is_string( $path ) && ! file_exists( $path ) ) {
- return;
- }
- // Make sure one file exists if path is an array.
- if ( is_array( $path ) ) {
- $exists = false;
- foreach ( $path as $file ) {
- if ( file_exists( $file ) ) {
- $exists = true;
- }
- }
- if ( ! $exists ) {
- return;
- }
- }
- // Store the template data.
- self::$templates[] = array(
- 'group' => isset( $args['group'] ) ? $args['group'] : false,
- 'path' => is_string( $path ) ? array( $path ) : $path,
- );
- }
- /**
- * Registers the core templates with the builder.
- *
- * @since 1.10.3
- * @return void
- */
- static private function register_core_templates() {
- $templates = glob( FL_BUILDER_DIR . 'data/*' );
- $paths = array();
- // glob() will return false on error so cast as an array() just in case.
- foreach ( (array) $templates as $template ) {
- if ( 'templates.dat' == basename( $template ) ) {
- continue;
- }
- $paths[] = $template;
- }
- self::register_templates( $paths );
- }
- /**
- * Applies a core template and can be overridden by extensions to
- * apply something else that is being shown in the selector.
- *
- * @since 1.0
- * @since 1.5.7. Added logic for overriding core templates.
- * @param int $index The index of the template to apply.
- * @param bool $append Whether to append the new template or replacing the existing layout.
- * @param string $type The type of template to apply.
- * @return void
- */
- static public function apply_template( $index = 0, $append = false, $type = 'layout' ) {
- // Allow extensions to hook into applying a template.
- $override = apply_filters( 'fl_builder_override_apply_template', false, array(
- 'index' => $index,
- 'append' => $append,
- 'type' => $type,
- ) );
- // Return if we have an override from the filter.
- if ( $override ) {
- return $override;
- }
- // Apply a core template.
- return self::apply_core_template( $index, $append, $type );
- }
- /**
- * Applies a core template and cannot be overridden by extensions.
- *
- * @since 1.10
- * @param int $index The index of the template to apply.
- * @param bool $append Whether to append the new template or replacing the existing layout.
- * @param string $type The type of template to apply.
- * @return array
- */
- static public function apply_core_template( $index = 0, $append = false, $type = 'layout' ) {
- $template = self::get_template( $index, $type );
- $row_position = self::next_node_position( 'row' );
- // Delete existing nodes and settings?
- if ( ! $append ) {
- self::delete_layout_data( 'draft' );
- self::delete_layout_settings( 'draft' );
- }
- // Only move forward if we have template nodes.
- if ( isset( $template->nodes ) ) {
- // Get new ids for the template nodes.
- $template->nodes = self::generate_new_node_ids( $template->nodes );
- // Get the existing layout data and settings.
- $layout_data = self::get_layout_data();
- $layout_settings = self::get_layout_settings();
- // Reposition rows?
- if ( $append ) {
- foreach ( $template->nodes as $node_id => $node ) {
- if ( 'row' == $node->type ) {
- $template->nodes[ $node_id ]->position += $row_position;
- }
- }
- }
- // Merge and update the layout data.
- $data = array_merge( $layout_data, $template->nodes );
- self::update_layout_data( $data );
- // Merge and update the layout settings.
- if ( isset( $template->settings ) ) {
- $settings = self::merge_layout_settings( $layout_settings, $template->settings );
- self::update_layout_settings( $settings );
- }
- }
- // Delete old asset cache.
- self::delete_asset_cache();
- // Return the layout.
- return array(
- 'layout' => FLBuilderAJAXLayout::render(),
- 'config' => FLBuilderUISettingsForms::get_node_js_config(),
- );
- }
- /**
- * Returns data for a core template.
- *
- * @since 1.0
- * @param int $index The index of the template.
- * @param string $type The type of template to get. Currently either layout, row or module.
- * @return object
- */
- static public function get_template( $index, $type = 'layout' ) {
- $templates = self::get_templates( $type );
- $template = isset( $templates[ $index ] ) ? $templates[ $index ] : false;
- if ( $template && isset( $template->nodes ) ) {
- $template->nodes = maybe_unserialize( $template->nodes );
- }
- return $template;
- }
- /**
- * Returns data for all core or third party templates.
- *
- * @since 1.0
- * @param string $type Either layout, row or module
- * @param bool $cached
- * @return array
- */
- static public function get_templates( $type = 'layout', $cached = true ) {
- // Pull from dat files if cached is false or we don't have saved data.
- if ( ! $cached || ! self::$template_data ) {
- self::$template_data = array();
- foreach ( self::$templates as $args ) {
- foreach ( $args['path'] as $path ) {
- // Make sure the template file exists.
- if ( ! file_exists( $path ) ) {
- continue;
- }
- // Get the unserialized template data.
- if ( stristr( $path, '.php' ) ) {
- ob_start();
- include $path;
- $unserialized = unserialize( ob_get_clean() );
- } else {
- $unserialized = fl_maybe_fix_unserialize( file_get_contents( $path ) );
- }
- // Make sure we have an unserialized array.
- if ( ! is_array( $unserialized ) ) {
- continue;
- }
- // Group and cache the template data.
- foreach ( $unserialized as $template_type => $template_data ) {
- if ( ! isset( self::$template_data[ $template_type ] ) ) {
- self::$template_data[ $template_type ] = array();
- }
- foreach ( $template_data as $key => $template ) {
- // Add the main group to each template.
- $template_data[ $key ]->group = $args['group'];
- // Reserialize the node data as it's expensive to store in memory.
- if ( isset( $template->nodes ) ) {
- $template_data[ $key ]->nodes = serialize( $template_data[ $key ]->nodes );
- }
- }
- self::$template_data[ $template_type ] = array_merge( self::$template_data[ $template_type ], $template_data );
- }
- }
- }
- }
- $templates = isset( self::$template_data[ $type ] ) ? self::$template_data[ $type ] : array();
- return apply_filters( 'fl_builder_get_templates', $templates, $type );
- }
- /**
- * Checks to see if any templates exist.
- *
- * @since 1.8
- * @return bool
- */
- static public function has_templates() {
- return apply_filters( 'fl_builder_has_templates', ( count( self::get_templates() ) > 0 ) );
- }
- /**
- * Returns template data needed for the template selector.
- * Can also return data for row, column and module templates if
- * a template type is passed.
- *
- * @since 1.5.7
- * @param string $type Either layout, row or module
- * @return array
- */
- static public function get_template_selector_data( $type = 'layout' ) {
- $type = apply_filters( 'fl_builder_template_selector_data_type', $type );
- $categorized = array();
- $templates = array();
- $core_categories = array(
- 'general' => __( 'General', 'fl-builder' ),
- 'landing' => __( 'Landing Pages', 'fl-builder' ),
- 'company' => __( 'Content Pages', 'fl-builder' ),
- );
- $groups = array();
- // Build the the templates array.
- foreach ( self::get_templates( $type ) as $key => $template ) {
- if ( 'module' == $type && isset( $template->nodes ) ) {
- $nodes = maybe_unserialize( $template->nodes );
- $node = array_shift( $nodes );
- if ( ! isset( $node->settings ) || ! isset( self::$modules[ $node->settings->type ] ) ) {
- continue;
- }
- }
- if ( strstr( $template->image, '://' ) || strstr( $template->image, ';base64,' ) ) {
- $image = $template->image;
- } else {
- $image = FL_BUILDER_URL . 'img/templates/' . ( empty( $template->image ) ? 'blank.jpg' : $template->image );
- }
- $templates[] = apply_filters( 'fl_builder_template_details', array(
- 'id' => $key,
- 'name' => $template->name,
- 'image' => $image,
- 'author' => '',
- 'category' => isset( $template->category ) ? $template->category : $template->categories,
- 'tags' => array(),
- 'group' => $template->group,
- 'type' => 'core',
- 'kind' => 'template',
- 'content' => ! in_array( $type, array( 'row', 'column', 'module' ) ) ? 'layout' : $type,
- ), $template );
- }
- // Build the categorized templates array and groups array.
- foreach ( $templates as $i => $template ) {
- // Make sure we have a template category and it's an array.
- if ( ! isset( $template['category'] ) ) {
- $template['category'] = array(
- 'uncategorized' => __( 'Uncategorized', 'fl-builder' ),
- );
- } elseif ( is_string( $template['category'] ) ) {
- $template['category'] = array(
- $template['category'] => $core_categories[ $template['category'] ],
- );
- }
- // Get template group data.
- $template_groups = array();
- if ( ! $template['group'] ) {
- // If we don't have a group, use categories as groups.
- foreach ( $template['category'] as $cat_name ) {
- $template_groups[] = $cat_name;
- }
- // Clear the categories since we're using groups instead.
- $template['category'] = array(
- 'none' => '',
- );
- } elseif ( is_string( $template['group'] ) ) {
- // Make sure template group is an array.
- $template_groups = array( $template['group'] );
- } else {
- $template_groups = $template['group'];
- }
- // Add to the groups array.
- $template['group'] = array();
- foreach ( $template_groups as $group_name ) {
- $group_key = sanitize_key( $group_name );
- if ( ! isset( $groups[ $group_key ] ) ) {
- $groups[ $group_key ] = array(
- 'name' => $group_name,
- 'categories' => array(),
- );
- }
- foreach ( $template['category'] as $cat_key => $cat_name ) {
- if ( ! isset( $groups[ $group_key ]['categories'][ $cat_key ] ) ) {
- $groups[ $group_key ]['categories'][ $cat_key ] = array(
- 'name' => $cat_name,
- );
- }
- }
- $template['group'][] = $group_key;
- }
- // Add to the categorized array.
- foreach ( $template['category'] as $cat_key => $cat_name ) {
- // Add the category if we don't have it yet.
- if ( ! isset( $categorized[ $cat_key ] ) ) {
- $categorized[ $cat_key ] = array(
- 'name' => $cat_name,
- 'templates' => array(),
- );
- }
- $categorized[ $cat_key ]['templates'][] = $template;
- }
- $templates[ $i ] = $template;
- }
- // Return both the templates and categorized templates array.
- return apply_filters( 'fl_builder_template_selector_data', array(
- 'templates' => $templates,
- 'categorized' => $categorized,
- 'groups' => $groups,
- ), $type );
- }
- /**
- * Returns data for row templates to be shown in the UI panel.
- *
- * @since 1.8
- * @return array
- */
- static public function get_row_templates_data() {
- return apply_filters( 'fl_builder_row_templates_data', self::get_template_selector_data( 'row' ) );
- }
- /**
- * Returns data for column templates to be shown in the UI panel.
- *
- * @since 2.1
- * @return array
- */
- static public function get_column_templates_data() {
- return apply_filters( 'fl_builder_column_templates_data', self::get_template_selector_data( 'column' ) );
- }
- /**
- * Returns data for module templates to be shown in the UI panel.
- *
- * @since 1.8
- * @return array
- */
- static public function get_module_templates_data() {
- return apply_filters( 'fl_builder_module_templates_data', self::get_template_selector_data( 'module' ) );
- }
- /**
- * Get color presets.
- *
- * @since 1.6.4
- * @return object
- */
- static public function get_color_presets() {
- $settings = get_option( '_fl_builder_color_presets', array() );
- return apply_filters( 'fl_builder_color_presets', $settings );
- }
- /**
- * Save color presets.
- *
- * @since 1.6.4
- * @param array $presets The new color presets collection.
- * @return object
- */
- static public function save_color_presets( $presets = array() ) {
- return update_option( '_fl_builder_color_presets', $presets );
- }
- /**
- * Returns whether the UI has been white labeled or not.
- *
- * @since 2.1
- * @return bool
- */
- static public function is_white_labeled() {
- if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
- return FLBuilderWhiteLabel::is_white_labeled();
- }
- return false;
- }
- /**
- * Returns whether the inline editing is enabled.
- *
- * @since 2.1
- * @return bool
- */
- static public function is_inline_enabled() {
- return apply_filters( 'fl_inline_editing_enabled', true );
- }
- /**
- * Returns whether the Ace Editor error checking is enabled.
- *
- * @since 2.1
- * @return bool
- */
- static public function is_codechecking_enabled() {
- return apply_filters( 'fl_code_checking_enabled', true );
- }
- /**
- * Returns Ace Editor defaults as an array.
- *
- * @since 2.1
- * @return array
- */
- static public function ace_editor_settings() {
- $defaults = array(
- 'enableBasicAutocompletion' => true,
- 'enableLiveAutocompletion' => true,
- 'enableSnippets' => false,
- 'showLineNumbers' => false,
- 'showFoldWidgets' => false,
- );
- return apply_filters( 'fl_ace_editor_settings', $defaults );
- }
- /**
- * Returns the custom branding string.
- *
- * @since 1.3.1
- * @return string
- */
- static public function get_branding() {
- if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
- return FLBuilderWhiteLabel::get_branding();
- }
- return __( 'Beaver Builder', 'fl-builder' );
- }
- /**
- * Returns the custom branding icon URL.
- *
- * @since 1.3.7
- * @return string
- */
- static public function get_branding_icon() {
- if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
- return FLBuilderWhiteLabel::get_branding_icon();
- }
- return FL_BUILDER_URL . 'img/beaver.png';
- }
- /**
- * Returns an array of slugs for all enabled icon sets.
- *
- * @since 1.4.6
- * @return array
- */
- static public function get_enabled_icons() {
- $value = self::get_admin_settings_option( '_fl_builder_enabled_icons', true );
- return ! $value ? array( 'font-awesome-5-regular', 'font-awesome-5-solid', 'font-awesome-5-brands', 'foundation-icons', 'dashicons' ) : $value;
- }
- /**
- * Check if the current user has the specific capabilities
- *
- * @param string $cap The capability to evaluate if it's single or multiple (comma separated) value
- * @return bool
- */
- static public function current_user_has_capability( $cap ) {
- if ( strstr( $cap, ',' ) ) {
- $parts = explode( ',', $cap );
- foreach ( $parts as $part ) {
- if ( current_user_can( trim( $part ) ) ) {
- return true;
- }
- }
- return false;
- } else {
- return current_user_can( $cap );
- }
- }
- /**
- * Returns the default settings for the builder's help button.
- *
- * @since 1.4.9
- * @return array
- */
- static public function get_help_button_defaults() {
- $defaults = array(
- 'enabled' => true,
- 'tour' => true,
- 'video' => true,
- 'video_embed' => '<iframe src="https://player.vimeo.com/video/240550556?autoplay=1" width="420" height="315" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>',
- 'knowledge_base' => true,
- 'knowledge_base_url' => self::get_store_url( 'knowledge-base', array(
- 'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-pro' ),
- 'utm_source' => 'builder-ui',
- 'utm_campaign' => 'kb-help-button',
- ) ),
- 'forums' => true,
- 'forums_url' => self::get_store_url( 'knowledge-base', array(
- 'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-pro' ),
- 'utm_source' => 'builder-ui',
- 'utm_campaign' => 'forums-help-button',
- ) ),
- );
- return $defaults;
- }
- /**
- * Returns the settings for the builder's help button.
- *
- * @since 1.4.9
- * @return array
- */
- static public function get_help_button_settings() {
- if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
- return FLBuilderWhiteLabel::get_help_button_settings();
- }
- return self::get_help_button_defaults();
- }
- /**
- * Get row resize settings
- *
- * @since 2.0
- * @return array
- */
- static public function get_row_resize_settings() {
- $defaults = array(
- 'userCanResizeRows' => true,
- 'minAllowedWidth' => 300,
- 'maxAllowedWidth' => false,
- );
- $settings = apply_filters( 'fl_row_resize_settings', $defaults );
- // Ensure everything is still defined after filter
- $settings = wp_parse_args( $settings, $defaults );
- // Min width can't go lower than 100px
- if ( false == $settings['minAllowedWidth'] || $settings['minAllowedWidth'] < 100 ) {
- $settings['minAllowedWidth'] = 100;
- }
- // Convert string numbers to int
- if ( is_string( $settings['minAllowedWidth'] ) ) {
- $settings['minAllowedWidth'] = intval( $settings['minAllowedWidth'] );
- }
- if ( is_string( $settings['maxAllowedWidth'] ) ) {
- $settings['maxAllowedWidth'] = intval( $settings['maxAllowedWidth'] );
- }
- // Check user capability
- if ( ! FLBuilderUserAccess::current_user_can( 'unrestricted_editing' ) ) {
- $settings['userCanResizeRows'] = false;
- }
- return $settings;
- }
- /**
- * Filter the row settings to remove max width field
- *
- * @since 2.0
- * @return array
- */
- static public function filter_row_settings_for_resize( $form, $id ) {
- if ( 'row' == $id && ! FLBuilderModel::user_can_resize_rows() ) {
- unset( $form['tabs']['style']['sections']['general']['fields']['max_content_width'] );
- }
- return $form;
- }
- /**
- * Check if user has the ability to resize rows
- *
- * @since 2.0
- * @return bool
- */
- static public function user_can_resize_rows() {
- $args = self::get_row_resize_settings();
- return $args['userCanResizeRows'];
- }
- /**
- * Returns an array of account data for all integrated services.
- *
- * @since 1.5.4
- * @return array
- */
- static public function get_services() {
- return get_option( '_fl_builder_services', array() );
- }
- /**
- * Updates the account data for an integrated service.
- *
- * @since 1.5.4
- * @param string $service The service id.
- * @param string $account The account name.
- * @param array $data The account data.
- * @return void
- */
- static public function update_services( $service, $account, $data ) {
- $services = self::get_services();
- $account = sanitize_text_field( $account );
- if ( ! isset( $services[ $service ] ) ) {
- $services[ $service ] = array();
- }
- $services[ $service ][ $account ] = $data;
- update_option( '_fl_builder_services', $services );
- }
- /**
- * Deletes an account for an integrated service.
- *
- * @since 1.5.4
- * @param string $service The service id.
- * @param string $account The account name.
- * @return void
- */
- static public function delete_service_account( $service, $account ) {
- $services = self::get_services();
- if ( isset( $services[ $service ][ $account ] ) ) {
- unset( $services[ $service ][ $account ] );
- }
- if ( 0 === count( $services[ $service ] ) ) {
- unset( $services[ $service ] );
- }
- update_option( '_fl_builder_services', $services );
- }
- /**
- * Returns an option from the database for
- * the admin settings page.
- *
- * @since 1.5.7
- * @param string $key The option key.
- * @param bool $network_override Whether to allow the network admin setting to be overridden on subsites.
- * @return mixed
- */
- static public function get_admin_settings_option( $key, $network_override = true ) {
- if ( is_network_admin() ) {
- // Get the site-wide option if we're in the network admin.
- $value = get_site_option( $key );
- } elseif ( ! $network_override && class_exists( 'FLBuilderMultisiteSettings' ) ) {
- // Get the site-wide option if there's no network override.
- $value = get_site_option( $key );
- } elseif ( class_exists( 'FLBuilderMultisiteSettings' ) ) {
- // Network overrides are allowed. Return the subsite option if it exists.
- $value = get_option( $key );
- $value = false === $value ? get_site_option( $key ) : $value;
- } else {
- // This must be a single site install. Get the single site option.
- $value = get_option( $key );
- }
- return $value;
- }
- /**
- * Updates an option from the admin settings page.
- *
- * @since 1.5.7
- * @param string $key The option key.
- * @param mixed $value The value to update.
- * @param bool $network_override Whether to allow the network admin setting to be overridden on subsites.
- * @return mixed
- */
- static public function update_admin_settings_option( $key, $value, $network_override = true ) {
- if ( is_network_admin() ) {
- // Update the site-wide option since we're in the network admin.
- update_site_option( $key, $value );
- } elseif ( $network_override && FLBuilderAdminSettings::multisite_support() && ! isset( $_POST['fl-override-ms'] ) ) {
- // Delete the option if we don't have a network override.
- delete_option( $key );
- } else {
- // Update the option for single install or subsite.
- update_option( $key, $value );
- }
- }
- /**
- * Returns the plugin basename for Beaver Builder.
- *
- * @since 1.0
- * @return string
- */
- static public function plugin_basename() {
- return plugin_basename( FL_BUILDER_DIR . 'fl-builder.php' );
- }
- /**
- * Deletes almost all database data and asset cache for the builder.
- * We don't delete _fl_builder_enabled, _fl_builder_data and _fl_builder_draft
- * so layouts can be recovered should the plugin be installed again.
- *
- * @since 1.0
- * @return void
- */
- static public function uninstall_database() {
- if ( current_user_can( 'delete_plugins' ) ) {
- // Delete builder options.
- delete_option( '_fl_builder_settings' );
- delete_option( '_fl_builder_enabled_modules' );
- delete_option( '_fl_builder_enabled_templates' );
- delete_option( '_fl_builder_templates_override' );
- delete_option( '_fl_builder_templates_override_rows' );
- delete_option( '_fl_builder_templates_override_columns' );
- delete_option( '_fl_builder_templates_override_modules' );
- delete_option( '_fl_builder_post_types' );
- delete_option( '_fl_builder_enabled_icons' );
- delete_option( '_fl_builder_branding' );
- delete_option( '_fl_builder_branding_icon' );
- delete_option( '_fl_builder_theme_branding' );
- delete_option( '_fl_builder_user_access' );
- delete_option( '_fl_builder_help_button' );
- delete_option( '_fl_builder_color_presets' );
- // Delete builder user meta.
- delete_metadata( 'user', 0, '_fl_builder_launched', 1, true );
- // Delete uploaded files and folders.
- $upload_dir = self::get_upload_dir();
- fl_builder_filesystem()->rmdir( $upload_dir['path'], true );
- // Deactivate and delete the plugin.
- if ( ! function_exists( 'deactivate_plugins' ) ) {
- require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
- }
- deactivate_plugins( array( self::plugin_basename() ), false, is_network_admin() );
- delete_plugins( array( self::plugin_basename() ) );
- // Redirect to the plugins page.
- wp_redirect( admin_url( 'plugins.php?deleted=true&plugin_status=all&paged=1&s=' ) );
- exit;
- }
- }
- /**
- * @since 1.6.4.3
- * @deprecated 1.8
- */
- static public function get_theme_branding() {
- _deprecated_function( __METHOD__, '1.8', 'FLBuilderWhiteLabel::get_theme_branding()' );
- if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
- return FLBuilderWhiteLabel::get_theme_branding();
- }
- }
- /**
- * @since 1.0
- * @deprecated 1.8
- */
- static public function save_templates( $templates = array() ) {
- _deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::save_templates()' );
- if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
- FLBuilderCoreTemplatesAdmin::save_templates( $templates );
- }
- }
- /**
- * @since 1.0
- * @deprecated 1.8
- */
- static public function save_template( $settings ) {
- _deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::save_template()' );
- if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
- FLBuilderCoreTemplatesAdmin::save_template( $settings );
- }
- }
- /**
- * @since 1.0
- * @deprecated 1.8
- */
- static public function update_template( $old_index, $settings ) {
- _deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::update_template()' );
- if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
- FLBuilderCoreTemplatesAdmin::update_template( $old_index, $settings );
- }
- }
- /**
- * @since 1.0
- * @deprecated 1.8
- */
- static public function delete_template( $index ) {
- _deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::delete_template()' );
- if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
- FLBuilderCoreTemplatesAdmin::delete_template( $index );
- }
- }
- /**
- * @since 1.3.9
- * @deprecated 1.10
- */
- static public function get_editing_capability() {
- _deprecated_function( __METHOD__, '1.10' );
- return 'edit_posts';
- }
- /**
- * @since 1.7
- * @deprecated 1.10
- */
- static public function current_user_has_editing_capability() {
- _deprecated_function( __METHOD__, '1.10', 'FLBuilderUserAccess::current_user_can()' );
- return FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
- }
- /**
- * @since 1.6.3
- * @deprecated 1.10
- */
- static public function get_global_templates_editing_capability() {
- _deprecated_function( __METHOD__, '1.10', 'FLBuilderUserAccess::current_user_can' );
- return 'edit_posts';
- }
- /**
- * @since 1.5.7
- * @deprecated 1.10
- */
- static public function user_templates_admin_enabled() {
- _deprecated_function( __METHOD__, '1.10', 'FLBuilderUserAccess::current_user_can( "builder_admin" )' );
- return FLBuilderUserAccess::current_user_can( 'builder_admin' );
- }
- /**
- * @since 1.0
- * @deprecated 2.0
- */
- static public function get_module_category_slug( $name ) {
- _deprecated_function( __METHOD__, '2.0' );
- return sanitize_html_class( $name );
- }
- /**
- * @since 1.8
- * @deprecated 2.0
- */
- static public function get_template_selector_filter_data() {
- _deprecated_function( __METHOD__, '2.0' );
- return array();
- }
- }
- FLBuilderModel::init();
|