functions.php 132 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144
  1. <?php
  2. if (!defined('HTMLY')) die('HTMLy');
  3. use \Michelf\MarkdownExtra;
  4. use \Suin\RSSWriter\Feed;
  5. use \Suin\RSSWriter\Channel;
  6. use \Suin\RSSWriter\Item;
  7. // Get blog post with more info about the path. Sorted by filename.
  8. function get_blog_posts()
  9. {
  10. static $_posts = array();
  11. $url = 'cache/index/index-posts.txt';
  12. if (!file_exists($url)) {
  13. rebuilt_cache('all');
  14. }
  15. $_posts = unserialize(file_get_contents($url));
  16. return $_posts;
  17. }
  18. // Get static page path.
  19. function get_static_pages()
  20. {
  21. static $_page = array();
  22. $url = 'cache/index/index-pages.txt';
  23. if (!file_exists($url)) {
  24. rebuilt_cache('all');
  25. }
  26. $_page = unserialize(file_get_contents($url));
  27. return $_page;
  28. }
  29. // Get static subpage path.
  30. function get_static_subpages($static = null)
  31. {
  32. static $_sub_page = array();
  33. $url = 'cache/index/index-subpages.txt';
  34. if (!file_exists($url)) {
  35. rebuilt_cache('all');
  36. }
  37. $_sub_page = unserialize(file_get_contents($url));
  38. if ($static != null) {
  39. $stringLen = strlen($static);
  40. return array_filter($_sub_page, function ($sub_page) use ($static, $stringLen) {
  41. $x = str_replace('content/static/', '', $sub_page['dirname']);
  42. $y = explode('.', $x);
  43. if (isset($y[1])) {
  44. $z = $y[1];
  45. } else {
  46. $z = $x;
  47. }
  48. if ($z == $static) {
  49. return true;
  50. }
  51. return false;
  52. });
  53. }
  54. return $_sub_page;
  55. }
  56. // Get author name.
  57. function get_author_name()
  58. {
  59. static $_author = array();
  60. $url = 'cache/index/index-author.txt';
  61. if (!file_exists($url)) {
  62. rebuilt_cache('all');
  63. }
  64. $_author = unserialize(file_get_contents($url));
  65. return $_author;
  66. }
  67. // Get posts draft.
  68. function get_draft_posts()
  69. {
  70. static $_draft = array();
  71. $url = 'cache/index/index-draft.txt';
  72. if (!file_exists($url)) {
  73. rebuilt_cache('all');
  74. }
  75. $_draft = unserialize(file_get_contents($url));
  76. return $_draft;
  77. }
  78. // Get static page draft.
  79. function get_draft_pages()
  80. {
  81. static $_draftPage = array();
  82. $tmp = array();
  83. $tmp = glob('content/static/draft/*.md', GLOB_NOSORT);
  84. if (is_array($tmp)) {
  85. foreach ($tmp as $file) {
  86. $_draftPage[] = pathinfo($file);
  87. }
  88. }
  89. usort($_draftPage, "sortfile_a");
  90. return $_draftPage;
  91. }
  92. // Get static subpage draft.
  93. function get_draft_subpages($static = null)
  94. {
  95. static $_draftSubpage = array();
  96. $tmp = array();
  97. $tmp = glob('content/static/*/draft/*.md', GLOB_NOSORT);
  98. if (is_array($tmp)) {
  99. foreach ($tmp as $file) {
  100. $_draftSubpage[] = pathinfo($file);
  101. }
  102. }
  103. usort($_draftSubpage, "sortfile_a");
  104. if ($static != null) {
  105. $stringLen = strlen($static);
  106. return array_filter($_draftSubpage, function ($sub_page) use ($static, $stringLen) {
  107. $x = explode('/', $sub_page['dirname']);
  108. $y = explode('.', $x[2]);
  109. if (isset($y[1])) {
  110. $z = $y[1];
  111. } else {
  112. $z = $y[0];
  113. }
  114. if ($z == $static) {
  115. return true;
  116. }
  117. return false;
  118. });
  119. }
  120. return $_draftSubpage;
  121. }
  122. // Get scheduled posts.
  123. function get_scheduled_posts()
  124. {
  125. static $_scheduled = array();
  126. $url = 'cache/index/index-scheduled.txt';
  127. if (!file_exists($url)) {
  128. rebuilt_cache('all');
  129. }
  130. $_scheduled = unserialize(file_get_contents($url));
  131. return $_scheduled;
  132. }
  133. // Get category info files.
  134. function get_category_files()
  135. {
  136. static $_desc = array();
  137. $url = 'cache/index/index-category-files.txt';
  138. if (!file_exists($url)) {
  139. rebuilt_cache('all');
  140. }
  141. $_desc = unserialize(file_get_contents($url));
  142. return $_desc;
  143. }
  144. // Get category folder.
  145. function get_category_folder()
  146. {
  147. static $_dfolder = array();
  148. $tmp = array();
  149. $tmp = glob('content/*/blog/*/', GLOB_ONLYDIR);
  150. if (is_array($tmp)) {
  151. foreach ($tmp as $dir) {
  152. $_dfolder[] = $dir;
  153. }
  154. }
  155. return $_dfolder;
  156. }
  157. // Get category slug.
  158. function get_category_slug()
  159. {
  160. static $_cslug = array();
  161. $url = 'cache/index/index-category.txt';
  162. if (!file_exists($url)) {
  163. rebuilt_cache('all');
  164. }
  165. $_cslug = unserialize(file_get_contents($url));
  166. return $_cslug;
  167. }
  168. // Get backup file.
  169. function get_zip_files()
  170. {
  171. static $_zip = array();
  172. $_zip = glob('backup/*.zip');
  173. return $_zip;
  174. }
  175. // Get images in content/images folder
  176. function scan_images() {
  177. static $_images = array();
  178. $tmp = array();
  179. $tmp = array_filter(glob('content/images/*', GLOB_NOSORT), 'is_file');
  180. if (is_array($tmp)) {
  181. foreach ($tmp as $file) {
  182. $_images[] = pathinfo($file);
  183. }
  184. }
  185. usort($_images, "sortfile_d");
  186. return $_images;
  187. }
  188. // usort function. Sort by filename.
  189. function sortfile_a($a, $b)
  190. {
  191. return $a['basename'] == $b['basename'] ? 0 : (($a['basename'] > $b['basename']) ? 1 : -1);
  192. }
  193. // usort function.
  194. function sortfile_d($a, $b)
  195. {
  196. return $a['basename'] == $b['basename'] ? 0 : (($a['basename'] < $b['basename']) ? 1 : -1);
  197. }
  198. // usort function. Sort by date.
  199. function sortdate($a, $b)
  200. {
  201. return $a->date == $b->date ? 0 : (($a->date < $b->date) ? 1 : -1);
  202. }
  203. // Rebuilt cache index
  204. function rebuilt_cache($type = null)
  205. {
  206. $dir = 'cache/index';
  207. $posts_cache = array();
  208. $page_cache = array();
  209. $subpage_cache = array();
  210. $author_cache = array();
  211. $scheduled_cache = array();
  212. $category_cache = array();
  213. $draft_cache = array();
  214. if (!is_dir($dir)) {
  215. mkdir($dir, 0775, true);
  216. }
  217. // Rebuilt posts index
  218. $tmp = array();
  219. $ctmp = array();
  220. $tmp = glob('content/*/blog/*/*/*.md', GLOB_NOSORT);
  221. if (is_array($tmp)) {
  222. foreach ($tmp as $file) {
  223. if(strpos($file, '/draft/') === false) {
  224. $posts_cache[] = pathinfo($file);
  225. $pc = explode('/', $file);
  226. $ctmp[] = $pc[3];
  227. }
  228. }
  229. }
  230. usort($posts_cache, "sortfile_d");
  231. $posts_string = serialize($posts_cache);
  232. file_put_contents('cache/index/index-posts.txt', print_r($posts_string, true), LOCK_EX);
  233. // Rebuilt scheduled posts index
  234. $stmp = array();
  235. $stmp = glob('content/*/*/*/*/scheduled/*.md', GLOB_NOSORT);
  236. if (is_array($stmp)) {
  237. foreach ($stmp as $file) {
  238. $scheduled_cache[] = pathinfo($file);
  239. $ss = explode('/', $file);
  240. $ctmp[] = $ss[3];
  241. }
  242. }
  243. usort($scheduled_cache, "sortfile_d");
  244. $scheduled_string = serialize($scheduled_cache);
  245. file_put_contents('cache/index/index-scheduled.txt', print_r($scheduled_string, true), LOCK_EX);
  246. // Rebuilt draft posts index
  247. $drf = array();
  248. $drf = glob('content/*/*/*/draft/*.md', GLOB_NOSORT);
  249. if (is_array($drf)) {
  250. foreach ($drf as $file) {
  251. $draft_cache[] = pathinfo($file);
  252. $dd = explode('/', $file);
  253. $ctmp[] = $dd[3];
  254. }
  255. }
  256. usort($draft_cache, "sortfile_d");
  257. $draft_string = serialize($draft_cache);
  258. file_put_contents('cache/index/index-draft.txt', print_r($draft_string, true), LOCK_EX);
  259. // Rebuilt category files index
  260. $ftmp = array();
  261. $ftmp = glob('content/data/category/*.md', GLOB_NOSORT);
  262. if (is_array($ftmp)) {
  263. foreach ($ftmp as $file) {
  264. $category_cache[] = pathinfo($file);
  265. $ctmp[] = pathinfo($file, PATHINFO_FILENAME);
  266. }
  267. }
  268. usort($category_cache, "sortfile_a");
  269. $category_string = serialize($category_cache);
  270. file_put_contents('cache/index/index-category-files.txt', print_r($category_string, true), LOCK_EX);
  271. // Rebuilt category slug index
  272. $dirc = array();
  273. $dirc = array_push($ctmp, 'uncategorized');
  274. $dirc = array_unique($ctmp, SORT_REGULAR);
  275. file_put_contents('cache/index/index-category.txt', print_r(serialize($dirc), true), LOCK_EX);
  276. // Rebuilt static page index
  277. $ptmp = array();
  278. $ptmp = glob('content/static/*.md', GLOB_NOSORT);
  279. natsort($ptmp);
  280. if (is_array($ptmp)) {
  281. foreach ($ptmp as $file) {
  282. if(strpos($file, '/draft/') === false) {
  283. $page_cache[] = pathinfo($file);
  284. }
  285. }
  286. }
  287. $page_string = serialize($page_cache);
  288. file_put_contents('cache/index/index-pages.txt', print_r($page_string, true), LOCK_EX);
  289. // Rebuilt subpage index
  290. $sptmp = array();
  291. $sptmp = glob('content/static/*/*.md', GLOB_NOSORT);
  292. natsort($sptmp);
  293. if (is_array($sptmp)) {
  294. foreach ($sptmp as $file) {
  295. if(strpos($file, '/draft/') === false) {
  296. $subpage_cache[] = pathinfo($file);
  297. }
  298. }
  299. }
  300. $subpage_string = serialize($subpage_cache);
  301. file_put_contents('cache/index/index-subpages.txt', print_r($subpage_string, true), LOCK_EX);
  302. // Rebuilt user profile index
  303. $atmp = array();
  304. $atmp = glob('content/*/author.md', GLOB_NOSORT);
  305. if (is_array($atmp)) {
  306. foreach ($atmp as $file) {
  307. $author_cache[] = pathinfo($file);
  308. }
  309. }
  310. usort($author_cache, "sortfile_a");
  311. $author_string = serialize($author_cache);
  312. file_put_contents('cache/index/index-author.txt', print_r($author_string, true), LOCK_EX);
  313. // Remove the widget cache
  314. foreach (glob('cache/widget/*.cache', GLOB_NOSORT) as $file) {
  315. unlink($file);
  316. }
  317. }
  318. // Return blog posts.
  319. function get_posts($posts, $page = 1, $perpage = 0)
  320. {
  321. if (empty($posts)) {
  322. $posts = get_blog_posts();
  323. }
  324. $tmp = array();
  325. $views = array();
  326. // Extract a specific page with results
  327. $posts = array_slice($posts, ($page - 1) * $perpage, $perpage);
  328. $cList = category_list(true);
  329. $auto = config('toc.automatic');
  330. $counter = config('views.counter');
  331. $viewsFile = "content/data/views.json";
  332. if (file_exists($viewsFile) && $counter == 'true') {
  333. $views = json_decode(file_get_contents($viewsFile), true);
  334. }
  335. foreach ($posts as $index => $v) {
  336. $post = new stdClass;
  337. $filepath = $v['dirname'] . '/' . $v['basename'];
  338. // Extract the date
  339. $arr = explode('_', $v['basename']);
  340. // dirname string
  341. $dirname = $v['dirname'];
  342. // Author string
  343. $str = explode('/', $dirname);
  344. $author = $str[1];
  345. foreach ($cList as $a => $t) {
  346. if ($t['0'] === $str[3]) {
  347. $post->category = '<a href="' . site_url() . 'category/' . $t['0'] . '">' . $t['1'] . '</a>';
  348. $post->categoryUrl = site_url() . 'category/' . $t['0'];
  349. $post->categoryCount = $t['2'];
  350. $post->categorySlug = $t['0'];
  351. $post->categoryMd = $t['0'] . '.md';
  352. $post->categoryTitle = $t['1'];
  353. $post->categoryb = '<a itemprop="item" href="' . site_url() . 'category/' . $t['0'] . '"><span itemprop="name">' . $t['1'] . '</span></a>';
  354. }
  355. }
  356. $type = $str[4];
  357. $post->ct = $str[3];
  358. // The post author + author url
  359. $post->author = $author;
  360. $post->authorUrl = site_url() . 'author/' . $author;
  361. $post->authorRss = site_url() . 'author/' . $author . '/feed';
  362. $profile = get_author($author);
  363. if (isset($profile[0])) {
  364. $post->authorName = $profile[0]->name;
  365. $post->authorDescription = $profile[0]->description;
  366. $post->authorAbout = $profile[0]->about;
  367. $post->authorAvatar = $profile[0]->avatar;
  368. $post->authorRaw = $profile[0]->raw;
  369. } else {
  370. $post->authorName = $author;
  371. $post->authorDescription = i18n('Author_Description');
  372. $post->authorAbout = $post->authorDescription;
  373. $post->authorAvatar = site_url() . 'system/resources/images/logo-small.png';
  374. $post->authorRaw = $post->authorDescription;
  375. }
  376. $post->type = $type;
  377. $dt = str_replace($dirname, '', $arr[0]);
  378. $t = str_replace('-', '', $dt);
  379. $time = new DateTime($t);
  380. $timestamp = $time->format("Y-m-d H:i:s");
  381. // The post date
  382. $post->date = strtotime($timestamp);
  383. $post->lastMod = strtotime(date('Y-m-d H:i:s', filemtime($filepath)));
  384. // The archive per day
  385. $post->archive = site_url() . 'archive/' . date('Y-m', $post->date);
  386. if (permalink_type() == 'default') {
  387. $post->url = site_url() . date('Y/m', $post->date) . '/' . str_replace('.md', '', $arr[2]);
  388. } else {
  389. $post->url = site_url() . permalink_type() . '/' . str_replace('.md', '', $arr[2]);
  390. }
  391. $post->slug = str_replace('.md', '', $arr[2]);
  392. $post->file = $filepath;
  393. $content = file_get_contents($filepath);
  394. // Extract the title and body
  395. $post->title = get_content_tag('t', $content, 'Untitled post: ' . format_date($post->lastMod, 'l, j F Y, H:i'));
  396. $post->image = get_content_tag('image', $content);
  397. $post->video = get_content_tag('video', $content);
  398. $post->link = get_content_tag('link', $content);
  399. $post->quote = get_content_tag('quote', $content);
  400. $post->audio = get_content_tag('audio', $content);
  401. $tag = array();
  402. $url = array();
  403. $bc = array();
  404. $rel = array();
  405. $tagt = get_content_tag('tag', $content);
  406. $t = explode(',', rtrim($arr[1], ','));
  407. if(!empty($tagt)) {
  408. $tl = explode(',', rtrim($tagt, ','));
  409. if (count($tl) == count($t)) {
  410. $tCom = array_combine($t, $tl);
  411. } else {
  412. $tCom = array_combine($t, $t);
  413. }
  414. foreach ($tCom as $key => $val) {
  415. if(!empty($val)) {
  416. $tag[] = array($val, site_url() . 'tag/' . strtolower($key));
  417. } else {
  418. $tag[] = array($key, site_url() . 'tag/' . strtolower($key));
  419. }
  420. }
  421. } else {
  422. foreach ($t as $tt) {
  423. $tag[] = array($tt, site_url() . 'tag/' . strtolower($tt));
  424. }
  425. }
  426. foreach ($tag as $a) {
  427. $url[] = '<a rel="tag" href="' . $a[1] . '">' . $a[0] . '</a>';
  428. $bc[] = '<span><a href="' . $a[1] . '">' . $a[0] . '</a></span>';
  429. }
  430. $post->tag = implode(' ', $url);
  431. $post->tagb = implode(' » ', $bc);
  432. $post->related = $post->categorySlug. ',' .$post->url;
  433. $more = explode('<!--more-->', $content);
  434. if (isset($more['1'])) {
  435. $content = $more['0'] . '<!--more--><div class="more-wrapper"><a id="more"></a></div>' . $more['1'];
  436. }
  437. // Get the contents and convert it to HTML
  438. $post->body = MarkdownExtra::defaultTransform(remove_html_comments($content));
  439. $post->description = get_content_tag("d", $content, get_description($post->body));
  440. $word_count = str_word_count(strip_tags($post->body));
  441. $post->readTime = ceil($word_count / 200);
  442. $toc = explode('<!--toc-->', $post->body);
  443. if (isset($toc['1'])) {
  444. $post->body = insert_toc('post-' . $post->date, $toc['0'], $toc['1']);
  445. } else {
  446. if ($auto === 'true') {
  447. $post->body = automatic_toc($post->body, 'post-' . $post->date);
  448. }
  449. }
  450. if ($counter == 'true') {
  451. $post->views = get_views('post_' . $post->slug, $views);
  452. } else {
  453. $post->views = null;
  454. }
  455. $post->raw = $content;
  456. $tmp[] = $post;
  457. }
  458. return $tmp;
  459. }
  460. function get_pages($pages, $page = 1, $perpage = 0)
  461. {
  462. if (empty($pages)) {
  463. $pages = get_static_pages();
  464. }
  465. $tmp = array();
  466. $auto = config('toc.automatic');
  467. $counter = config('views.counter');
  468. $viewsFile = "content/data/views.json";
  469. if (file_exists($viewsFile) && $counter == 'true') {
  470. $views = json_decode(file_get_contents($viewsFile), true);
  471. }
  472. // Extract a specific page with results
  473. $pages = array_slice($pages, ($page - 1) * $perpage, $perpage);
  474. foreach ($pages as $index => $v) {
  475. $post = new stdClass;
  476. // The static page URL
  477. $fn = explode('.', $v['filename']);
  478. if (isset($fn[1])) {
  479. $url = $fn[1];
  480. } else {
  481. $url= $v['filename'];
  482. }
  483. $post->url = site_url() . $url;
  484. $post->file = $v['dirname'] . '/' . $v['basename'];
  485. $post->lastMod = strtotime(date('Y-m-d H:i:s', filemtime($post->file)));
  486. $post->md = $v['basename'];
  487. $post->slug = $url;
  488. $post->parent = null;
  489. $post->parentSlug = null;
  490. // Get the contents and convert it to HTML
  491. $content = file_get_contents($post->file);
  492. // Extract the title and body
  493. $post->title = get_content_tag('t', $content, 'Untitled static page: ' . format_date($post->lastMod, 'l, j F Y, H:i'));
  494. // Get the contents and convert it to HTML
  495. $post->body = MarkdownExtra::defaultTransform(remove_html_comments($content));
  496. $post->description = get_content_tag("d", $content, get_description($post->body));
  497. $word_count = str_word_count(strip_tags($post->body));
  498. $post->readTime = ceil($word_count / 200);
  499. $toc = explode('<!--toc-->', $post->body);
  500. if (isset($toc['1'])) {
  501. $post->body = insert_toc('page-' . $post->slug, $toc['0'], $toc['1']);
  502. } else {
  503. if ($auto === 'true') {
  504. $post->body = automatic_toc($post->body, 'page-' . $post->slug);
  505. }
  506. }
  507. if ($counter == 'true') {
  508. $post->views = get_views('page_' . $post->slug, $views);
  509. } else {
  510. $post->views = null;
  511. }
  512. $post->raw = $content;
  513. $tmp[] = $post;
  514. }
  515. return $tmp;
  516. }
  517. function get_subpages($sub_pages, $page = 1, $perpage = 0)
  518. {
  519. if (empty($sub_pages)) {
  520. $sub_pages = get_static_subpages();
  521. }
  522. $tmp = array();
  523. $auto = config('toc.automatic');
  524. $counter = config('views.counter');
  525. $viewsFile = "content/data/views.json";
  526. if (file_exists($viewsFile) && $counter == 'true') {
  527. $views = json_decode(file_get_contents($viewsFile), true);
  528. }
  529. // Extract a specific page with results
  530. $sub_pages = array_slice($sub_pages, ($page - 1) * $perpage, $perpage);
  531. foreach ($sub_pages as $index => $v) {
  532. $post = new stdClass;
  533. $fd = str_replace(dirname($v['dirname']) . '/', '', $v['dirname']);
  534. $st = explode('.', $fd);
  535. if (isset($st[1])) {
  536. $static = $st[1];
  537. } else {
  538. $static = $fd;
  539. }
  540. // The static page URL
  541. $fn = explode('.', $v['filename']);
  542. if (isset($fn[1])) {
  543. $url = $fn[1];
  544. } else {
  545. $url= $v['filename'];
  546. }
  547. $post->url = site_url() . $static . "/" . $url;
  548. $post->file = $v['dirname'] . '/' . $v['basename'];
  549. $post->lastMod = strtotime(date('Y-m-d H:i:s', filemtime($post->file)));
  550. $post->md = $v['basename'];
  551. $post->slug = $url;
  552. $post->parent = $fd;
  553. $post->parentSlug = $static;
  554. // Get the contents and convert it to HTML
  555. $content = file_get_contents($post->file);
  556. // Extract the title and body
  557. $post->title = get_content_tag('t', $content, 'Untitled static subpage: ' . format_date($post->lastMod, 'l, j F Y, H:i'));
  558. // Get the contents and convert it to HTML
  559. $post->body = MarkdownExtra::defaultTransform(remove_html_comments($content));
  560. $post->description = get_content_tag("d", $content, get_description($post->body));
  561. $word_count = str_word_count(strip_tags($post->body));
  562. $post->readTime = ceil($word_count / 200);
  563. $toc = explode('<!--toc-->', $post->body);
  564. if (isset($toc['1'])) {
  565. $post->body = insert_toc('subpage-' . $post->slug, $toc['0'], $toc['1']);
  566. } else {
  567. if ($auto === 'true') {
  568. $post->body = automatic_toc($post->body, 'subpage-' . $post->slug);
  569. }
  570. }
  571. if ($counter == 'true') {
  572. $post->views = get_views('subpage_' . $post->parentSlug .'.'. $post->slug, $views);
  573. } else {
  574. $post->views = null;
  575. }
  576. $post->raw = $content;
  577. $tmp[] = $post;
  578. }
  579. return $tmp;
  580. }
  581. // Find post by year, month and name, previous, and next.
  582. function find_post($year, $month, $name)
  583. {
  584. $posts = get_blog_posts();
  585. foreach ($posts as $index => $v) {
  586. $arr = explode('_', $v['basename']);
  587. if ((strpos($arr[0], "$year-$month") !== false && strtolower($arr[2]) === strtolower($name . '.md')) || ($year === NULL && strtolower($arr[2]) === strtolower($name . '.md'))) {
  588. // Use the get_posts method to return
  589. // a properly parsed object
  590. $ar = get_posts($posts, $index + 1, 1);
  591. $nx = get_posts($posts, $index, 1);
  592. $pr = get_posts($posts, $index + 2, 1);
  593. if ($index == 0) {
  594. if (isset($pr[0])) {
  595. return array(
  596. 'current' => $ar[0],
  597. 'prev' => $pr[0]
  598. );
  599. } else {
  600. return array(
  601. 'current' => $ar[0],
  602. 'prev' => null
  603. );
  604. }
  605. } elseif (count($posts) == $index + 1) {
  606. return array(
  607. 'current' => $ar[0],
  608. 'next' => $nx[0]
  609. );
  610. } else {
  611. return array(
  612. 'current' => $ar[0],
  613. 'next' => $nx[0],
  614. 'prev' => $pr[0]
  615. );
  616. }
  617. }
  618. }
  619. }
  620. // Return static page.
  621. function find_page($static = null, $pages = null)
  622. {
  623. if (empty($pages)) {
  624. $pages = get_static_pages();
  625. }
  626. $tmp = array();
  627. if (!empty($pages)) {
  628. foreach ($pages as $index => $v) {
  629. if (is_null($static)) {
  630. return get_pages($pages, 1, null);
  631. } elseif (stripos($v['basename'], $static . '.md') !== false) {
  632. // Use the get_posts method to return
  633. // a properly parsed object
  634. $ar = get_pages($pages, $index + 1, 1);
  635. $nx = get_pages($pages, $index, 1);
  636. $pr = get_pages($pages, $index + 2, 1);
  637. if ($index == 0) {
  638. if (isset($pr[0])) {
  639. return array(
  640. 'current' => $ar[0],
  641. 'prev' => $pr[0]
  642. );
  643. } else {
  644. return array(
  645. 'current' => $ar[0],
  646. 'prev' => null
  647. );
  648. }
  649. } elseif (count($pages) == $index + 1) {
  650. return array(
  651. 'current' => $ar[0],
  652. 'next' => $nx[0]
  653. );
  654. } else {
  655. return array(
  656. 'current' => $ar[0],
  657. 'next' => $nx[0],
  658. 'prev' => $pr[0]
  659. );
  660. }
  661. }
  662. }
  663. }
  664. return $tmp;
  665. }
  666. // Return static subpage.
  667. function find_subpage($static, $sub_static = null, $sub_pages = null)
  668. {
  669. if (empty($sub_pages)) {
  670. $sub_pages = array_values(get_static_subpages($static));
  671. }
  672. $tmp = array();
  673. if (!empty($sub_pages)) {
  674. foreach ($sub_pages as $index => $v) {
  675. if (is_null($sub_static)) {
  676. return get_subpages($sub_pages, 1, null);
  677. } elseif (stripos($v['basename'], $sub_static . '.md') !== false) {
  678. // Use the get_posts method to return
  679. // a properly parsed object
  680. $ar = get_subpages($sub_pages, $index + 1, 1);
  681. $nx = get_subpages($sub_pages, $index, 1);
  682. $pr = get_subpages($sub_pages, $index + 2, 1);
  683. if ($index == 0) {
  684. if (isset($pr[0])) {
  685. return array(
  686. 'current' => $ar[0],
  687. 'prev' => $pr[0]
  688. );
  689. } else {
  690. return array(
  691. 'current' => $ar[0],
  692. 'prev' => null
  693. );
  694. }
  695. } elseif (count($sub_pages) == $index + 1) {
  696. return array(
  697. 'current' => $ar[0],
  698. 'next' => $nx[0]
  699. );
  700. } else {
  701. return array(
  702. 'current' => $ar[0],
  703. 'next' => $nx[0],
  704. 'prev' => $pr[0]
  705. );
  706. }
  707. }
  708. }
  709. }
  710. return $tmp;
  711. }
  712. // Return category page.
  713. function get_category($category, $page, $perpage, $random = null)
  714. {
  715. if (is_null($category)) return array();
  716. $posts = get_blog_posts();
  717. if ($random === true) {
  718. shuffle($posts);
  719. }
  720. $tmp = array();
  721. if (empty($perpage)) {
  722. $perpage = 10;
  723. }
  724. foreach ($posts as $index => $v) {
  725. // dirname string
  726. $dirname = $v['dirname'];
  727. $str = explode('/', $dirname);
  728. if (strtolower($category) === strtolower($str[3])) {
  729. $tmp[] = $v;
  730. }
  731. }
  732. if (empty($tmp)) {
  733. return $tmp;
  734. }
  735. $tmp = array_unique($tmp, SORT_REGULAR);
  736. return $tmp = array(get_posts($tmp, $page, $perpage), count($tmp));
  737. }
  738. // Return category info.
  739. function get_category_info($category = null)
  740. {
  741. $tmp = array();
  742. $cslug= get_category_slug();
  743. if (!empty($cslug)) {
  744. asort($cslug);
  745. if (is_null($category)) {
  746. foreach ($cslug as $key => $c){
  747. $ctmp = read_category_info($c);
  748. if (!empty($ctmp[0])) {
  749. $tmp[] = $ctmp[0];
  750. } else {
  751. $tmp[] = default_category($c);
  752. }
  753. }
  754. } else {
  755. foreach ($cslug as $key => $c){
  756. if ($c === $category) {
  757. $ctmp = read_category_info($category);
  758. if (!empty($ctmp[0])) {
  759. $tmp[] = $ctmp[0];
  760. } else {
  761. $tmp[] = default_category($category);
  762. }
  763. }
  764. }
  765. }
  766. } else {
  767. $tmp[] = default_category($category);
  768. }
  769. return $tmp;
  770. }
  771. function read_category_info($category)
  772. {
  773. $tmp = array();
  774. $cFiles = get_category_files();
  775. if (!empty($cFiles)) {
  776. foreach ($cFiles as $index => $v) {
  777. if ($v['basename'] == $category . '.md' ) {
  778. $desc = new stdClass;
  779. // The filename
  780. $filename = $v['dirname'] . '/' . $v['basename'];
  781. $url= $v['filename'];
  782. $desc->url = site_url() . 'category/' . $url;
  783. $desc->md = $v['basename'];
  784. $desc->slug = $url;
  785. $desc->count = get_categorycount($url);
  786. $desc->file = $filename;
  787. $desc->rss = $desc->url . '/feed';
  788. // Get the contents and convert it to HTML
  789. $content = file_get_contents($desc->file);
  790. // Extract the title and body
  791. $desc->title = get_content_tag('t', $content, $category);
  792. // Get the contents and convert it to HTML
  793. $desc->body = MarkdownExtra::defaultTransform(remove_html_comments($content));
  794. $desc->description = get_content_tag("d", $content, get_description($desc->body));
  795. $toc = explode('<!--toc-->', $desc->body);
  796. if (isset($toc['1'])) {
  797. $desc->body = insert_toc('taxonomy-' . $desc->slug, $toc['0'], $toc['1']);
  798. }
  799. $desc->raw = $content;
  800. $tmp[] = $desc;
  801. }
  802. }
  803. }
  804. return $tmp;
  805. }
  806. // Return default category
  807. function default_category($category = null)
  808. {
  809. $tmp = array();
  810. $desc = new stdClass;
  811. if (is_null($category) || $category == 'uncategorized') {
  812. $desc->title = i18n("Uncategorized");
  813. $desc->url = site_url() . 'category/uncategorized';
  814. $desc->slug = 'uncategorized';
  815. $desc->body = '<p>' . i18n('Uncategorized_comment') . '</p>';
  816. $desc->md = 'uncategorized.md';
  817. $desc->description = i18n('Uncategorized_comment');
  818. $desc->file = '';
  819. $desc->count = get_categorycount($desc->slug);
  820. $desc->rss = $desc->url . '/feed';
  821. $desc->raw = $desc->body;
  822. } else{
  823. $desc->title = $category;
  824. $desc->url = site_url() . 'category/' . $category;
  825. $desc->slug = $category;
  826. $desc->body = '<p>' . i18n('All_blog_posts') . ': ' . $category . '</p>';
  827. $desc->md = $category . '.md';
  828. $desc->description = i18n('All_blog_posts') . ': ' . $category;
  829. $desc->file = '';
  830. $desc->count = get_categorycount($category);
  831. $desc->rss = $desc->url . '/feed';
  832. $desc->raw = $desc->body;
  833. }
  834. return $tmp[] = $desc;
  835. }
  836. // Return category list
  837. function category_list($custom = null)
  838. {
  839. $dir = "cache/widget";
  840. $filename = "cache/widget/category.list.cache";
  841. $tmp = array();
  842. $cat = array();
  843. $list = array();
  844. $cList = '';
  845. if (!is_dir($dir)) {
  846. mkdir($dir, 0775, true);
  847. }
  848. if (file_exists($filename)) {
  849. $cat = unserialize(file_get_contents($filename));
  850. } else {
  851. $arr = get_category_info(null);
  852. foreach ($arr as $i => $a) {
  853. $cat[] = array($a->slug, $a->title, $a->count, $a->description, $a->body, $a->raw, $a->file, $a->rss);
  854. }
  855. $tmp = serialize($cat);
  856. file_put_contents($filename, print_r($tmp, true), LOCK_EX);
  857. }
  858. if(!empty($custom)) {
  859. return $cat;
  860. }
  861. $cList .= '<ul>';
  862. foreach ($cat as $k => $v) {
  863. if ($v['2'] !== 0) {
  864. $cList .= '<li><a href="' . site_url() . 'category/' . $v['0'] . '">' . $v['1'] . '</a> <span>('. $v['2'] .')</span></li>';
  865. }
  866. }
  867. $cList .= '</ul>';
  868. return $cList;
  869. }
  870. // Return type page.
  871. function get_type($type, $page, $perpage)
  872. {
  873. if (is_null($type)) return array();
  874. $posts = get_blog_posts();
  875. $tmp = array();
  876. if (empty($perpage)) {
  877. $perpage = 10;
  878. }
  879. foreach ($posts as $index => $v) {
  880. // dirname string
  881. $dirname = $v['dirname'];
  882. $str = explode('/', $dirname);
  883. if (strtolower($type) === strtolower($str[4])) {
  884. $tmp[] = $v;
  885. }
  886. }
  887. if (empty($tmp)) {
  888. return $tmp;
  889. }
  890. $tmp = array_unique($tmp, SORT_REGULAR);
  891. return $tmp = array(get_posts($tmp, $page, $perpage), count($tmp));
  892. }
  893. // Return tag page.
  894. function get_tag($tag, $page, $perpage, $random = null)
  895. {
  896. if (is_null($tag)) return array();
  897. $posts = get_blog_posts();
  898. if ($random === true) {
  899. shuffle($posts);
  900. }
  901. $tmp = array();
  902. foreach ($posts as $index => $v) {
  903. $str = explode('_', $v['basename']);
  904. $mtag = explode(',', rtrim($str[1], ','));
  905. $etag = explode(',', $tag);
  906. foreach ($mtag as $t) {
  907. foreach ($etag as $e) {
  908. $e = trim($e);
  909. if (strtolower($t) === strtolower($e)) {
  910. $tmp[] = $v;
  911. }
  912. }
  913. }
  914. }
  915. if (empty($tmp)) {
  916. return $tmp;
  917. }
  918. $tmp = array_unique($tmp, SORT_REGULAR);
  919. return $tmp = array(get_posts($tmp, $page, $perpage), count($tmp));
  920. }
  921. // Return archive page.
  922. function get_archive($req, $page, $perpage)
  923. {
  924. if (is_null($req)) return array();
  925. $posts = get_blog_posts();
  926. $tmp = array();
  927. foreach ($posts as $index => $v) {
  928. $str = explode('_', $v['basename']);
  929. if (strpos($str[0], "$req") !== false) {
  930. $tmp[] = $v;
  931. }
  932. }
  933. if (empty($tmp)) {
  934. return $tmp;
  935. }
  936. return $tmp = array(get_posts($tmp, $page, $perpage), count($tmp));
  937. }
  938. // Return posts list on profile.
  939. function get_profile_posts($name, $page, $perpage)
  940. {
  941. if (is_null($name)) return array();
  942. $posts = get_blog_posts();
  943. $tmp = array();
  944. foreach ($posts as $index => $v) {
  945. $str = explode('/', $v['dirname']);
  946. if (strtolower($name) === strtolower($str[1])) {
  947. $tmp[] = $v;
  948. }
  949. }
  950. if (empty($tmp)) {
  951. return $tmp;
  952. }
  953. return $tmp = array(get_posts($tmp, $page, $perpage), count($tmp));
  954. }
  955. // Return author info.
  956. function get_author($name)
  957. {
  958. if (is_null($name)) return array();
  959. $names = get_author_name();
  960. $tmp = array();
  961. if (!empty($names)) {
  962. foreach ($names as $index => $v) {
  963. $author = new stdClass;
  964. // dirname string
  965. $dirname = $v['dirname'];
  966. // Author string
  967. $str = explode('/', $dirname);
  968. $profile = $str[1];
  969. if ($name === $profile) {
  970. // Profile URL
  971. $filename = $v['dirname'] . '/' . $v['basename'];
  972. $author->file = $filename;
  973. $author->url = site_url() . 'author/' . $profile;
  974. $author->slug = $profile;
  975. // Get the contents and convert it to HTML
  976. $content = file_get_contents($author->file);
  977. // Extract the title and body
  978. $author->name = get_content_tag('t', $content, $author);
  979. // Get the contents and convert it to HTML
  980. $author->about = MarkdownExtra::defaultTransform(remove_html_comments($content));
  981. $author->description = get_content_tag("d", $content, get_description($author->about));
  982. $author->avatar = get_content_tag("image", $content, site_url() . 'system/resources/images/logo-small.png');
  983. $author->rss = $author->url . '/feed';
  984. $toc = explode('<!--toc-->', $author->about);
  985. if (isset($toc['1'])) {
  986. $author->about = insert_toc('profile-' . $author->slug, $toc['0'], $toc['1']);
  987. }
  988. $author->body = $author->about;
  989. $author->title = $author->name;
  990. $author->raw = $content;
  991. $tmp[] = $author;
  992. }
  993. }
  994. }
  995. return $tmp;
  996. }
  997. // Return default profile
  998. function default_profile($name)
  999. {
  1000. $tmp = array();
  1001. $author = new stdClass;
  1002. $author->name = $name;
  1003. $author->title = $name;
  1004. $author->about = '<p>' . i18n('Author_Description') . '</p>';
  1005. $author->body = '<p>' . i18n('Author_Description') . '</p>';
  1006. $author->description = i18n('Author_Description');
  1007. $author->avatar = site_url() . 'system/resources/images/logo-small.png';
  1008. $author->url = site_url(). 'author/' . $name;
  1009. $author->slug = $name;
  1010. $author->file = '';
  1011. $author->rss = $author->url . '/feed';
  1012. $author->raw = $author->about;
  1013. return $tmp[] = $author;
  1014. }
  1015. // Return frontpage content
  1016. function get_frontpage()
  1017. {
  1018. $front = new stdClass;
  1019. $filename = 'content/data/frontpage/frontpage.md';
  1020. if (file_exists($filename)) {
  1021. $content = file_get_contents($filename);
  1022. $front->file = $filename;
  1023. $front->title = get_content_tag('t', $content, 'Welcome');
  1024. $front->url = site_url() . 'front';
  1025. $front->slug = 'front';
  1026. $front->parent = null;
  1027. $front->parentSlug = null;
  1028. // Get the contents and convert it to HTML
  1029. $front->body = MarkdownExtra::defaultTransform(remove_html_comments($content));
  1030. $front->description = get_content_tag("d", $content, get_description($front->body));
  1031. $word_count = str_word_count(strip_tags($front->body));
  1032. $front->readTime = ceil($word_count / 200);
  1033. $front->views = null;
  1034. $toc = explode('<!--toc-->', $front->body);
  1035. if (isset($toc['1'])) {
  1036. $front->body = insert_toc('page-front', $toc['0'], $toc['1']);
  1037. }
  1038. $front->raw = $content;
  1039. } else {
  1040. $front->title = 'Welcome';
  1041. $front->url = site_url() . 'front';
  1042. $front->body = 'Welcome to our website.';
  1043. $front->file = null;
  1044. $front->slug = 'front';
  1045. $front->parent = null;
  1046. $front->parentSlug = null;
  1047. $front->description = $front->body;
  1048. $word_count = str_word_count(strip_tags($front->body));
  1049. $front->readTime = ceil($word_count / 200);
  1050. $front->views = null;
  1051. $front->raw = $front->body;
  1052. }
  1053. return $front;
  1054. }
  1055. // Return search page.
  1056. function get_keyword($keyword, $page, $perpage)
  1057. {
  1058. if (strlen($keyword) < 3) {
  1059. return array();
  1060. }
  1061. $posts = get_blog_posts();
  1062. $tmp = array();
  1063. $search = array();
  1064. $searchFile = "content/data/search.json";
  1065. if (file_exists($searchFile) && config('fulltext.search') == "true") {
  1066. $search = json_decode(file_get_contents($searchFile), true);
  1067. }
  1068. foreach ($posts as $index => $v) {
  1069. $arr = explode('_', $v['filename']);
  1070. if (isset($search['post_' . $arr[2]])) {
  1071. $filter = $search['post_' . $arr[2]];
  1072. } else {
  1073. $filter = $arr[1] . ' ' . $arr[2];
  1074. $keyword = remove_accent($keyword);
  1075. }
  1076. if (stripos($filter, trim($keyword)) !== false) {
  1077. if (!in_array($v, $tmp)) {
  1078. $tmp[] = $v;
  1079. }
  1080. }
  1081. }
  1082. if (empty($tmp)) {
  1083. return $tmp;
  1084. }
  1085. return $tmp = array(get_posts($tmp, $page, $perpage), count($tmp));
  1086. }
  1087. // Get related posts base on post category.
  1088. function get_related($tag, $custom = null, $count = null)
  1089. {
  1090. if (empty($count)) {
  1091. $count = config('related.count');
  1092. if (empty($count)) {
  1093. $count = 3;
  1094. }
  1095. }
  1096. $tmp = array();
  1097. $exp = explode(',', $tag);
  1098. $posts = get_category($exp[0], 1, $count + 1, true);
  1099. if ($posts) $posts = $posts[0];
  1100. $related = '';
  1101. $i = 1;
  1102. foreach ($posts as $post) {
  1103. if ($post->url !== $exp[1]) {
  1104. $tmp[] = $post;
  1105. if ($i++ >= $count)
  1106. break;
  1107. }
  1108. }
  1109. if (empty($custom)) {
  1110. if (!empty($tmp)) {
  1111. $related .= '<ul>';
  1112. foreach ($tmp as $post) {
  1113. $related .= '<li><a href="' . $post->url . '">' . $post->title . '</a></li>';
  1114. }
  1115. $related .= '</ul>';
  1116. return $related;
  1117. } else {
  1118. $related .= '<ul><li>' . i18n('No_related_post_found') . '</li></ul>';
  1119. return $related;
  1120. }
  1121. } else {
  1122. return $tmp;
  1123. }
  1124. }
  1125. // Return post count. Matching $var and $str provided.
  1126. function get_count($var, $str)
  1127. {
  1128. $posts = get_blog_posts();
  1129. $tmp = array();
  1130. foreach ($posts as $index => $v) {
  1131. if ($str === 'basename') {
  1132. $arr = explode('_', $v[$str]);
  1133. $url = $arr[0];
  1134. if (stripos($url, "$var") !== false) {
  1135. $tmp[] = $v;
  1136. }
  1137. } else {
  1138. if (stripos($v[$str], $var) !== false) {
  1139. $tmp[] = $v;
  1140. }
  1141. }
  1142. }
  1143. return count($tmp);
  1144. }
  1145. // Return category count. Matching $var
  1146. function get_categorycount($var)
  1147. {
  1148. $posts = get_blog_posts();
  1149. $tmp = array();
  1150. foreach ($posts as $index => $v) {
  1151. // dirname string
  1152. $dirname = $v['dirname'];
  1153. $str = explode('/', $dirname);
  1154. if (strtolower($var) === strtolower($str[3])) {
  1155. $tmp[] = $v;
  1156. }
  1157. }
  1158. return count($tmp);
  1159. }
  1160. // Return type count. Matching $var
  1161. function get_typecount($var)
  1162. {
  1163. $posts = get_blog_posts();
  1164. $tmp = array();
  1165. foreach ($posts as $index => $v) {
  1166. // dirname string
  1167. $dirname = $v['dirname'];
  1168. $str = explode('/', $dirname);
  1169. if (strtolower($var) === strtolower($str[4])) {
  1170. $tmp[] = $v;
  1171. }
  1172. }
  1173. return count($tmp);
  1174. }
  1175. // Return profile posts count. Matching $var
  1176. function get_profilecount($var)
  1177. {
  1178. $posts = get_blog_posts();
  1179. $tmp = array();
  1180. foreach ($posts as $index => $v) {
  1181. // dirname string
  1182. $dirname = $v['dirname'];
  1183. $str = explode('/', $dirname);
  1184. if (strtolower($var) === strtolower($str[1])) {
  1185. $tmp[] = $v;
  1186. }
  1187. }
  1188. return count($tmp);
  1189. }
  1190. // Return draft count. Matching $var
  1191. function get_draftcount($var)
  1192. {
  1193. $posts = get_draft_posts();
  1194. $tmp = array();
  1195. foreach ($posts as $index => $v) {
  1196. if (stripos($v['dirname'], '/' . $var . '/') !== false) {
  1197. $tmp[] = $v;
  1198. }
  1199. }
  1200. return count($tmp);
  1201. }
  1202. // Return scheduled post count. Matching $var
  1203. function get_scheduledcount($var)
  1204. {
  1205. $posts = get_scheduled_posts();
  1206. $tmp = array();
  1207. foreach ($posts as $index => $v) {
  1208. if (stripos($v['dirname'], '/' . $var . '/') !== false) {
  1209. $tmp[] = $v;
  1210. }
  1211. }
  1212. return count($tmp);
  1213. }
  1214. // Return tag count. Matching $var
  1215. function get_tagcount($var)
  1216. {
  1217. $posts = get_blog_posts();
  1218. $tmp = array();
  1219. foreach ($posts as $index => $v) {
  1220. $arr = explode('_', $v['basename']);
  1221. $mtag = explode(',', rtrim($arr[1], ','));
  1222. foreach ($mtag as $t) {
  1223. if (strtolower($t) === strtolower($var)) {
  1224. $tmp[] = $v;
  1225. }
  1226. }
  1227. }
  1228. return count($tmp);
  1229. }
  1230. // Return search result count
  1231. function keyword_count($keyword)
  1232. {
  1233. if (strlen($keyword) < 3) {
  1234. return array();
  1235. }
  1236. $posts = get_blog_posts();
  1237. $tmp = array();
  1238. $search = array();
  1239. $searchFile = "content/data/search.json";
  1240. if (file_exists($searchFile) && config('fulltext.search') == "true") {
  1241. $search = json_decode(file_get_contents($searchFile), true);
  1242. }
  1243. foreach ($posts as $index => $v) {
  1244. $arr = explode('_', $v['filename']);
  1245. if (isset($search['post_' . $arr[2]])) {
  1246. $filter = $search['post_' . $arr[2]];
  1247. } else {
  1248. $filter = $arr[1] . ' ' . $arr[2];
  1249. $keyword = remove_accent($keyword);
  1250. }
  1251. if (stripos($filter, trim($keyword)) !== false) {
  1252. if (!in_array($v, $tmp)) {
  1253. $tmp[] = $v;
  1254. }
  1255. }
  1256. }
  1257. $tmp = array_unique($tmp, SORT_REGULAR);
  1258. return count($tmp);
  1259. }
  1260. // Return recent posts
  1261. function recent_posts($custom = null, $count = null)
  1262. {
  1263. return get_recent('posts', 'list', $count, $custom);
  1264. }
  1265. // Return recent posts by category
  1266. function recent_category($category, $count = null, $custom = null)
  1267. {
  1268. return get_recent('category', $category, $count, $custom);
  1269. }
  1270. // Return recent posts by type
  1271. function recent_type($type, $count = null, $custom = null)
  1272. {
  1273. return get_recent('type', $type, $count, $custom);
  1274. }
  1275. // Return recent posts by tag
  1276. function recent_tag($tag, $count = null, $custom = null)
  1277. {
  1278. return get_recent('tag', $tag, $count, $custom);
  1279. }
  1280. // Return recent posts by author
  1281. function recent_profile_posts($name, $count = null, $custom = null)
  1282. {
  1283. return get_recent('profile', $name, $count, $custom);
  1284. }
  1285. function get_recent($filter, $var, $count = null, $custom = null)
  1286. {
  1287. if (is_null($var)) return array();
  1288. if (empty($count)) {
  1289. $count = config('recent.count');
  1290. if (empty($count)) {
  1291. $count = 5;
  1292. }
  1293. }
  1294. $dir = 'cache/widget';
  1295. $filename = 'cache/widget/recent.' . $filter . '.' . $var . '.cache';
  1296. $tmp = array();
  1297. $posts = array();
  1298. $recent = '';
  1299. if (!is_dir($dir)) {
  1300. mkdir($dir, 0775, true);
  1301. }
  1302. if (file_exists($filename)) {
  1303. $posts = unserialize(file_get_contents($filename));
  1304. if (count($posts) < $count) {
  1305. if ($filter == 'profile') {
  1306. $posts = get_profile_posts($var, 1, $count);
  1307. if ($posts) $posts = $posts[0];
  1308. } elseif ($filter == 'category') {
  1309. $posts = get_category($var, 1, $count);
  1310. if ($posts) $posts = $posts[0];
  1311. } elseif ($filter == 'type') {
  1312. $posts = get_type($var, 1, $count);
  1313. if ($posts) $posts = $posts[0];
  1314. } elseif ($filter == 'posts') {
  1315. $posts = get_posts(null, 1, $count);
  1316. } elseif ($filter == 'tag') {
  1317. $posts = get_tag($var, 1, $count);
  1318. if ($posts) $posts = $posts[0];
  1319. }
  1320. if (!empty($posts)) {
  1321. $tmp = serialize($posts);
  1322. file_put_contents($filename, print_r($tmp, true), LOCK_EX);
  1323. }
  1324. }
  1325. } else {
  1326. if ($filter == 'profile') {
  1327. $posts = get_profile_posts($var, 1, $count);
  1328. if ($posts) $posts = $posts[0];
  1329. } elseif ($filter == 'category') {
  1330. $posts = get_category($var, 1, $count);
  1331. if ($posts) $posts = $posts[0];
  1332. } elseif ($filter == 'type') {
  1333. $posts = get_type($var, 1, $count);
  1334. if ($posts) $posts = $posts[0];
  1335. } elseif ($filter == 'posts') {
  1336. $posts = get_posts(null, 1, $count);
  1337. } elseif ($filter == 'tag') {
  1338. $posts = get_tag($var, 1, $count);
  1339. if ($posts) $posts = $posts[0];
  1340. }
  1341. if (!empty($posts)) {
  1342. $tmp = serialize($posts);
  1343. file_put_contents($filename, print_r($tmp, true), LOCK_EX);
  1344. }
  1345. }
  1346. if (!empty($custom)) {
  1347. $arr = array();
  1348. $i = 1;
  1349. foreach ($posts as $post) {
  1350. $arr[] = $post;
  1351. if ($i++ >= $count)
  1352. break;
  1353. }
  1354. return $arr;
  1355. } else {
  1356. $i = 1;
  1357. $recent .= '<ul>';
  1358. foreach ($posts as $post) {
  1359. $recent .= '<li><a href="' . $post->url . '">' . $post->title . '</a></li>';
  1360. if ($i++ >= $count)
  1361. break;
  1362. }
  1363. if (empty($posts)) {
  1364. $recent .= '<li>' . i18n('No_posts_found') . '</li>';
  1365. }
  1366. $recent .= '</ul>';
  1367. return $recent;
  1368. }
  1369. }
  1370. // Return popular posts lists
  1371. function popular_posts($custom = null, $count = null)
  1372. {
  1373. static $_views = array();
  1374. $tmp = array();
  1375. $posts_list = get_blog_posts();
  1376. $pop = '';
  1377. if (empty($count)) {
  1378. $count = config('popular.count');
  1379. if (empty($count)) {
  1380. $count = 5;
  1381. }
  1382. }
  1383. if (config('views.counter') == 'true') {
  1384. if (empty($_views)) {
  1385. $filename = 'content/data/views.json';
  1386. if (file_exists($filename)) {
  1387. $_views = json_decode(file_get_contents($filename), true);
  1388. if(is_array($_views)) {
  1389. arsort($_views);
  1390. $i = 1;
  1391. foreach ($_views as $key => $val) {
  1392. $arr = explode('post_', $key);
  1393. if (isset($arr[1])) {
  1394. foreach($posts_list as $in => $f) {
  1395. $ex = explode('_', $f['basename']);
  1396. if ($ex[2] == $arr[1] . '.md') {
  1397. $tmp[] = $f;
  1398. if ($i++ >= $count)
  1399. break;
  1400. }
  1401. }
  1402. }
  1403. }
  1404. $dir = "cache/widget";
  1405. $filecache = "cache/widget/popular.cache";
  1406. $ar = array();
  1407. $posts = array();
  1408. if (!is_dir($dir)) {
  1409. mkdir($dir, 0775, true);
  1410. }
  1411. if (file_exists($filecache)) {
  1412. $posts = unserialize(file_get_contents($filecache));
  1413. if (count($posts) < $count) {
  1414. $posts = get_posts($tmp, 1, $count);
  1415. $ar = serialize($posts);
  1416. file_put_contents($filecache, print_r($ar, true), LOCK_EX);
  1417. }
  1418. } else {
  1419. $posts = get_posts($tmp, 1, $count);
  1420. $ar = serialize($posts);
  1421. file_put_contents($filecache, print_r($ar, true), LOCK_EX);
  1422. }
  1423. if (empty($custom)) {
  1424. $ix = 1;
  1425. $pop .= '<ul>';
  1426. foreach ($posts as $post) {
  1427. $pop .= '<li><a href="' . $post->url . '">' . $post->title . '</a></li>';
  1428. if ($ix++ >= $count)
  1429. break;
  1430. }
  1431. $pop .= '</ul>';
  1432. return $pop;
  1433. } else {
  1434. $arp = array();
  1435. $ix = 1;
  1436. foreach ($posts as $post) {
  1437. $arp[] = $post;
  1438. if ($ix++ >= $count)
  1439. break;
  1440. }
  1441. return $arp;
  1442. }
  1443. } else {
  1444. if(empty($custom)) {
  1445. $pop .= '<ul><li>No popular posts found</li></ul>';
  1446. return $pop;
  1447. } else {
  1448. return $tmp;
  1449. }
  1450. }
  1451. } else {
  1452. if (empty($custom)) {
  1453. $pop .= '<ul><li>No popular posts found</li></ul>';
  1454. return $pop;
  1455. } else {
  1456. return $tmp;
  1457. }
  1458. }
  1459. }
  1460. } else {
  1461. if (empty($custom)) {
  1462. $pop .= '<ul><li>No popular posts found</li></ul>';
  1463. return $pop;
  1464. } else {
  1465. return $tmp;
  1466. }
  1467. }
  1468. }
  1469. // Return an archive list, categorized by year and month.
  1470. function archive_list($custom = null)
  1471. {
  1472. $dir = "cache/widget";
  1473. $filename = "cache/widget/archive.cache";
  1474. $ar = array();
  1475. $arch = '';
  1476. if (!is_dir($dir)) {
  1477. mkdir($dir, 0775, true);
  1478. }
  1479. $posts = get_blog_posts();
  1480. $by_year = array();
  1481. $col = array();
  1482. if (!empty($posts)) {
  1483. if (!file_exists($filename)) {
  1484. foreach ($posts as $index => $v) {
  1485. $arr = explode('_', $v['filename']);
  1486. $date = $arr[0];
  1487. $data = explode('-', $date);
  1488. $col[] = $data;
  1489. }
  1490. foreach ($col as $row) {
  1491. $y = $row['0'];
  1492. $m = $row['1'];
  1493. $by_year[$y][] = $m;
  1494. }
  1495. $ar = serialize($by_year);
  1496. file_put_contents($filename, print_r($ar, true), LOCK_EX);
  1497. } else {
  1498. $by_year = unserialize(file_get_contents($filename));
  1499. }
  1500. # Most recent year first
  1501. krsort($by_year);
  1502. # Iterate for display
  1503. $i = 0;
  1504. $len = count($by_year);
  1505. if (empty($custom)) {
  1506. $cache_d = "cache/widget/archive.default.cache";
  1507. if (file_exists($cache_d)) {
  1508. $arch = unserialize(file_get_contents($cache_d));
  1509. return $arch;
  1510. } else {
  1511. foreach ($by_year as $year => $months) {
  1512. if ($i == 0) {
  1513. $class = 'expanded';
  1514. $arrow = '&#9660;';
  1515. } else {
  1516. $class = 'collapsed';
  1517. $arrow = '&#9658;';
  1518. }
  1519. $i++;
  1520. $by_month = array_count_values($months);
  1521. # Sort the months
  1522. krsort($by_month);
  1523. $script = <<<EOF
  1524. if (this.parentNode.className.indexOf('expanded') > -1){this.parentNode.className = 'collapsed';this.innerHTML = '&#9658;';} else {this.parentNode.className = 'expanded';this.innerHTML = '&#9660;';}
  1525. EOF;
  1526. $arch .= '<ul class="archivegroup">';
  1527. $arch .= '<li class="' . $class . '">';
  1528. $arch .= '<a href="javascript:void(0)" class="toggle" onclick="' . $script . '">' . $arrow . '</a> ';
  1529. $arch .= '<a href="' . site_url() . 'archive/' . $year . '">' . $year . '</a> ';
  1530. $arch .= '<span class="count">(' . count($months) . ')</span>';
  1531. $arch .= '<ul class="month">';
  1532. foreach ($by_month as $month => $count) {
  1533. $name = format_date(mktime(0, 0, 0, $month, 1, 2010), 'F');
  1534. $arch .= '<li class="item"><a href="' . site_url() . 'archive/' . $year . '-' . $month . '">' . $name . '</a>';
  1535. $arch .= ' <span class="count">(' . $count . ')</span></li>';
  1536. }
  1537. $arch .= '</ul>';
  1538. $arch .= '</li>';
  1539. $arch .= '</ul>';
  1540. }
  1541. $ar = serialize($arch);
  1542. file_put_contents($cache_d, $ar, LOCK_EX);
  1543. return $arch;
  1544. }
  1545. } elseif ($custom === 'month-year') {
  1546. $cache_my = "cache/widget/archive.month-year.cache";
  1547. if (file_exists($cache_my)) {
  1548. $arch = unserialize(file_get_contents($cache_my));
  1549. return $arch;
  1550. } else {
  1551. foreach ($by_year as $year => $months) {
  1552. $by_month = array_count_values($months);
  1553. # Sort the months
  1554. krsort($by_month);
  1555. foreach ($by_month as $month => $count) {
  1556. $name = format_date(mktime(0, 0, 0, $month, 1, 2010), 'F');
  1557. $arch .= '<li class="item"><a href="' . site_url() . 'archive/' . $year . '-' . $month . '">' . $name . ' ' . $year .'</a> ('.$count.')</li>';
  1558. }
  1559. }
  1560. $ar = serialize($arch);
  1561. file_put_contents($cache_my, $ar, LOCK_EX);
  1562. return $arch;
  1563. }
  1564. } elseif ($custom === 'year') {
  1565. $cache_y = "cache/widget/archive.year.cache";
  1566. if (file_exists($cache_y)) {
  1567. $arch = unserialize(file_get_contents($cache_y));
  1568. return $arch;
  1569. } else {
  1570. foreach ($by_year as $year => $months) {
  1571. $by_month = array_count_values($months);
  1572. # Sort the months
  1573. krsort($by_month);
  1574. $arch .= '<li class="item"><a href="' . site_url() . 'archive/' . $year . '">' . $year .'</a> ('. count($months) .')</li>';
  1575. }
  1576. $ar = serialize($arch);
  1577. file_put_contents($cache_y, $ar, LOCK_EX);
  1578. return $arch;
  1579. }
  1580. } else {
  1581. return $by_year;
  1582. }
  1583. }
  1584. }
  1585. // Return tag cloud.
  1586. function tag_cloud($custom = null)
  1587. {
  1588. $dir = "cache/widget";
  1589. $filename = "cache/widget/tags.cache";
  1590. $tg = array();
  1591. if (!is_dir($dir)) {
  1592. mkdir($dir, 0775, true);
  1593. }
  1594. $posts = get_blog_posts();
  1595. $tags = array();
  1596. $tagcloud_count = config('tagcloud.count');
  1597. if(empty($tagcloud_count)) {
  1598. $tagcloud_count = 40;
  1599. }
  1600. if (!empty($posts)) {
  1601. if (!file_exists($filename)) {
  1602. foreach ($posts as $index => $v) {
  1603. $arr = explode('_', $v['filename']);
  1604. $data = rtrim($arr[1], ',');
  1605. $mtag = explode(',', $data);
  1606. foreach ($mtag as $etag) {
  1607. $tags[] = strtolower($etag);
  1608. }
  1609. }
  1610. $tag_collection = array_count_values($tags);
  1611. ksort($tag_collection);
  1612. $tg = serialize($tag_collection);
  1613. file_put_contents($filename, print_r($tg, true), LOCK_EX);
  1614. } else {
  1615. $tag_collection = unserialize(file_get_contents($filename));
  1616. }
  1617. if(empty($custom)) {
  1618. $wrapper = '';
  1619. $cache_t = "cache/widget/tags.default.cache";
  1620. if (file_exists($cache_t)) {
  1621. $wrapper = unserialize(file_get_contents($cache_t));
  1622. return $wrapper;
  1623. } else {
  1624. // Font sizes
  1625. $max_size = 22; // max font size in %
  1626. $min_size = 8; // min font size in %
  1627. // Get the largest and smallest array values
  1628. $max_qty = max(array_values($tag_collection));
  1629. $min_qty = min(array_values($tag_collection));
  1630. // Find the range of values
  1631. $spread = $max_qty - $min_qty;
  1632. if (0 == $spread) { // we don't want to divide by zero
  1633. $spread = 1;
  1634. }
  1635. // Font-size increment
  1636. // this is the increase per tag quantity (times used)
  1637. $step = ($max_size - $min_size)/($spread);
  1638. arsort($tag_collection);
  1639. $sliced_tags = array_slice($tag_collection, 0, $tagcloud_count, true);
  1640. ksort($sliced_tags);
  1641. foreach ($sliced_tags as $tag => $count) {
  1642. $size = $min_size + (($count - $min_qty) * $step);
  1643. $wrapper .= ' <a class="tag-cloud-link" href="'. site_url(). 'tag/'. $tag .'" style="font-size:'. $size .'pt;">'.tag_i18n($tag).'</a> ';
  1644. }
  1645. $ar = serialize($wrapper);
  1646. file_put_contents($cache_t, $ar, LOCK_EX);
  1647. return $wrapper;
  1648. }
  1649. } else {
  1650. return $tag_collection;
  1651. }
  1652. } else {
  1653. if(empty($custom)) return;
  1654. return $tags;
  1655. }
  1656. }
  1657. // Helper function to determine whether
  1658. // to show the previous buttons
  1659. function has_prev($prev)
  1660. {
  1661. if (!empty($prev)) {
  1662. return array(
  1663. 'url' => $prev->url,
  1664. 'title' => $prev->title,
  1665. 'date' => $prev->date,
  1666. 'body' => $prev->body,
  1667. 'description' => $prev->description,
  1668. 'tag' => $prev->tag,
  1669. 'author' => $prev->author,
  1670. 'authorName' => $prev->authorName,
  1671. 'authorDescription' => $prev->authorDescription,
  1672. 'authorAbout' => $prev->authorAbout,
  1673. 'authorUrl' => $prev->authorUrl,
  1674. 'authorAvatar' => $prev->authorAvatar,
  1675. 'authorRss' => $prev->authorRss,
  1676. 'related' => $prev->related,
  1677. 'views' => $prev->views,
  1678. 'type' => $prev->type,
  1679. 'file' => $prev->file,
  1680. 'image' => $prev->image,
  1681. 'video' => $prev->video,
  1682. 'audio' => $prev->audio,
  1683. 'quote' => $prev->quote,
  1684. 'link' => $prev->link,
  1685. 'slug' => $prev->slug,
  1686. 'category' => $prev->category,
  1687. 'categoryUrl' => $prev->categoryUrl,
  1688. 'categoryCount' => $prev->categoryCount,
  1689. 'categorySlug' => $prev->categorySlug,
  1690. 'categoryMd' => $prev->categoryMd,
  1691. 'categoryTitle' => $prev->categoryTitle,
  1692. 'readTime' => $prev->readTime,
  1693. 'lastMod' => $prev->lastMod,
  1694. 'raw' => $prev->raw
  1695. );
  1696. }
  1697. }
  1698. // Helper function to determine whether
  1699. // to show the next buttons
  1700. function has_next($next)
  1701. {
  1702. if (!empty($next)) {
  1703. return array(
  1704. 'url' => $next->url,
  1705. 'title' => $next->title,
  1706. 'date' => $next->date,
  1707. 'body' => $next->body,
  1708. 'description' => $next->description,
  1709. 'tag' => $next->tag,
  1710. 'author' => $next->author,
  1711. 'authorName' => $next->authorName,
  1712. 'authorDescription' => $next->authorDescription,
  1713. 'authorAbout' => $next->authorAbout,
  1714. 'authorUrl' => $next->authorUrl,
  1715. 'authorAvatar' => $next->authorAvatar,
  1716. 'authorRss' => $next->authorRss,
  1717. 'related' => $next->related,
  1718. 'views' => $next->views,
  1719. 'type' => $next->type,
  1720. 'file' => $next->file,
  1721. 'image' => $next->image,
  1722. 'video' => $next->video,
  1723. 'audio' => $next->audio,
  1724. 'quote' => $next->quote,
  1725. 'link' => $next->link,
  1726. 'slug' => $next->slug,
  1727. 'category' => $next->category,
  1728. 'categoryUrl' => $next->categoryUrl,
  1729. 'categoryCount' => $next->categoryCount,
  1730. 'categorySlug' => $next->categorySlug,
  1731. 'categoryMd' => $next->categoryMd,
  1732. 'categoryTitle' => $next->categoryTitle,
  1733. 'readTime' => $next->readTime,
  1734. 'lastMod' => $next->lastMod,
  1735. 'raw' => $next->raw
  1736. );
  1737. }
  1738. }
  1739. function static_prev($prev)
  1740. {
  1741. if (!empty($prev)) {
  1742. return array(
  1743. 'url' => $prev->url,
  1744. 'title' => $prev->title,
  1745. 'body' => $prev->body,
  1746. 'description' => $prev->description,
  1747. 'views' => $prev->views,
  1748. 'md' => $prev->md,
  1749. 'slug' => $prev->slug,
  1750. 'parent' => $prev->parent,
  1751. 'parentSlug' => $prev->parentSlug,
  1752. 'file' => $prev->file,
  1753. 'readTime' => $prev->readTime,
  1754. 'lastMod' => $prev->lastMod,
  1755. 'raw' => $prev->raw
  1756. );
  1757. }
  1758. }
  1759. function static_next($next)
  1760. {
  1761. if (!empty($next)) {
  1762. return array(
  1763. 'url' => $next->url,
  1764. 'title' => $next->title,
  1765. 'body' => $next->body,
  1766. 'description' => $next->description,
  1767. 'views' => $next->views,
  1768. 'md' => $next->md,
  1769. 'slug' => $next->slug,
  1770. 'parent' => $next->parent,
  1771. 'parentSlug' => $next->parentSlug,
  1772. 'file' => $next->file,
  1773. 'readTime' => $next->readTime,
  1774. 'lastMod' => $next->lastMod,
  1775. 'raw' => $next->raw
  1776. );
  1777. }
  1778. }
  1779. // Helper function to determine whether
  1780. // to show the pagination buttons
  1781. function has_pagination($total, $perpage, $page = 1)
  1782. {
  1783. if (!$total) {
  1784. return false;
  1785. }
  1786. $totalPage = ceil($total / $perpage);
  1787. $number = i18n('Page') . ' ' . $page . ' ' . i18n('of') . ' ' . $totalPage;
  1788. $pager = get_pagination($total, $page, $perpage, 2);
  1789. return array(
  1790. 'prev' => $page > 1,
  1791. 'next' => $total > $page * $perpage,
  1792. 'pagenum' => $number,
  1793. 'html' => $pager,
  1794. 'items' => $total,
  1795. 'perpage' => $perpage
  1796. );
  1797. }
  1798. //function to return the pagination string
  1799. function get_pagination($totalitems, $page = 1, $perpage = 10, $adjacents = 1, $pagestring = '?page=')
  1800. {
  1801. //defaults
  1802. if(!$adjacents) $adjacents = 1;
  1803. if(!$perpage) $perpage = 10;
  1804. if(!$page) $page = 1;
  1805. //other vars
  1806. $prev = $page - 1; //previous page is page - 1
  1807. $next = $page + 1; //next page is page + 1
  1808. $lastpage = ceil($totalitems / $perpage); //lastpage is = total items / items per page, rounded up.
  1809. $lpm1 = $lastpage - 1; //last page minus 1
  1810. /*
  1811. Now we apply our rules and draw the pagination object.
  1812. We're actually saving the code to a variable in case we want to draw it more than once.
  1813. */
  1814. $pagination = '';
  1815. $curpage = strtok($_SERVER["REQUEST_URI"], '?');
  1816. if($lastpage > 1)
  1817. {
  1818. $pagination .= '<ul class="pagination">';
  1819. //newer button
  1820. if ($page > 2)
  1821. $pagination .= '<li class="page-item"><a class="page-link" href="'. $pagestring . $prev .'">« '. i18n('Newer') .'</a></li>';
  1822. else if ($page == 2)
  1823. $pagination .= '<li class="page-item"><a class="page-link" href="'. $curpage .'">« '. i18n('Newer') .'</a></li>';
  1824. else
  1825. $pagination .= '<li class="page-item disabled"><span class="page-link">« '. i18n('Newer') . '</span></li>';
  1826. //pages
  1827. if ($lastpage < 7 + ($adjacents * 2)) //not enough pages to bother breaking it up
  1828. {
  1829. for ($counter = 1; $counter <= $lastpage; $counter++)
  1830. {
  1831. if ($counter == 1 && $counter !== $page) // link 1st pagination page to parent page instead of ?page=1 for SEO
  1832. $pagination .= '<li class="page-item"><a class="page-link" href="'. $curpage .'">1</a></li>';
  1833. else if ($counter == $page)
  1834. $pagination .= '<li class="page-item active"><span class="page-link">'. $counter.'</span></li>';
  1835. else
  1836. $pagination .= '<li class="page-item"><a class="page-link" href="'. $curpage . $pagestring . $counter .'">'. $counter .'</a></li>';
  1837. }
  1838. }
  1839. elseif($lastpage >= 7 + ($adjacents * 2)) //enough pages to hide some
  1840. {
  1841. //close to beginning; only hide later pages
  1842. if($page < 1 + ($adjacents * 3))
  1843. {
  1844. for ($counter = 1; $counter < 4 + ($adjacents * 2); $counter++)
  1845. {
  1846. if ($counter == 1 && $counter !== $page) // link 1st pagination page to parent page instead of ?page=1 for SEO
  1847. $pagination .= '<li class="page-item"><a class="page-link" href="'. $curpage .'">1</a></li>';
  1848. else if ($counter == $page)
  1849. $pagination .= '<li class="page-item active"><span class="page-link">'. $counter .'</span></li>';
  1850. else
  1851. $pagination .= '<li class="page-item"><a class="page-link" href="'. $curpage . $pagestring . $counter .'">'. $counter .'</a></li>';
  1852. }
  1853. $pagination .= '<li class="page-item disabled"><span class="page-link">...</span></li>';
  1854. $pagination .= '<li class="page-item"><a class="page-link" href="'. $curpage . $pagestring . $lpm1 .'">'. $lpm1 .'</a></li>';
  1855. $pagination .= '<li class="page-item"><a class="page-link" href="'. $curpage . $pagestring . $lastpage .'">'. $lastpage .'</a></li>';
  1856. }
  1857. //in middle; hide some front and some back
  1858. elseif($lastpage - ($adjacents * 2) > $page && $page > ($adjacents * 2))
  1859. {
  1860. $pagination .= '<li class="page-item"><a class="page-link" href="' . $curpage .'">1</a></li>';
  1861. $pagination .= '<li class="page-item"><a class="page-link" href="'. $pagestring .'2">2</a></li>';
  1862. $pagination .= '<li class="page-item disabled"><span class="page-link">...</span></li>';
  1863. for ($counter = $page - $adjacents; $counter <= $page + $adjacents; $counter++)
  1864. {
  1865. if ($counter == $page)
  1866. $pagination .= '<li class="page-item active"><span class="page-link">'. $counter .'</span></li>';
  1867. else
  1868. $pagination .= '<li class="page-item"><a class="page-link" href="'. $curpage . $pagestring . $counter .'">'. $counter .'</a></li>';
  1869. }
  1870. $pagination .= '<li class="page-item disabled"><span class="page-link">...</span></li>';
  1871. $pagination .= '<li class="page-item"><a class="page-link" href="'. $curpage . $pagestring . $lpm1 .'">'. $lpm1 .'</a></li>';
  1872. $pagination .= '<li class="page-item"><a class="page-link" href="'. $curpage . $pagestring . $lastpage . '">'. $lastpage .'</a></li>';
  1873. }
  1874. //close to end; only hide early pages
  1875. else
  1876. {
  1877. $pagination .= '<li class="page-item"><a class="page-link" href="'. $curpage .'">1</a></li>';
  1878. $pagination .= '<li class="page-item"><a class="page-link" href="'. $pagestring .'2">2</a></li>';
  1879. $pagination .= '<li class="page-item disabled"><span class="page-link">...</span></li>';
  1880. for ($counter = $lastpage - (1 + ($adjacents * 3)); $counter <= $lastpage; $counter++)
  1881. {
  1882. if ($counter == $page)
  1883. $pagination .= '<li class="page-item active"><span class="page-link">'. $counter .'</span></li>';
  1884. else
  1885. $pagination .= '<li class="page-item"><a class="page-link" href="'. $curpage . $pagestring . $counter .'">'. $counter .'</a></li>';
  1886. }
  1887. }
  1888. }
  1889. //older button
  1890. if ($page < $counter - 1)
  1891. $pagination .= '<li class="page-item"><a class="page-link" href="'. $curpage . $pagestring . $next .'">'. i18n('Older') .' »</a></li>';
  1892. else
  1893. $pagination .= '<li class="page-item disabled"><span class="page-link">'. i18n('Older') .' »</span></li>';
  1894. $pagination .= '</ul>';
  1895. }
  1896. return $pagination;
  1897. }
  1898. // Get the meta description
  1899. function get_description($string, $char = null)
  1900. {
  1901. if(empty($char)) {
  1902. $char = config('description.char');
  1903. if(empty($char)) {
  1904. $char = 150;
  1905. }
  1906. }
  1907. if (strlen(strip_tags($string)) < $char) {
  1908. return safe_html(strip_tags($string));
  1909. } else {
  1910. $string = safe_html(strip_tags($string));
  1911. $string = substr($string, 0, $char);
  1912. $string = substr($string, 0, strrpos($string, ' '));
  1913. return $string;
  1914. }
  1915. }
  1916. // Get the teaser
  1917. function get_teaser($string, $url = null, $char = null)
  1918. {
  1919. $teaserType = config('teaser.type');
  1920. $more = config('read.more');
  1921. $behave = config('teaser.behave');
  1922. if(empty($more)) {
  1923. $more = 'Read more';
  1924. }
  1925. if(empty($char)) {
  1926. $char = config('teaser.char');
  1927. if(empty($char)) {
  1928. $char = 200;
  1929. }
  1930. }
  1931. if ($teaserType === 'full') {
  1932. $readMore = explode('<!--more-->', $string);
  1933. if (isset($readMore['1'])) {
  1934. $string = replace_href($readMore['0'], 'a', 'footnote-ref', $url);
  1935. return $string . '<div class="jump-link"><a class="read-more btn btn-cta-secondary" href="'. $url .'#more">' . $more . '</a></div>';
  1936. } else {
  1937. return $string;
  1938. }
  1939. } else {
  1940. if ($behave === 'check') {
  1941. $readMore = explode('<!--more-->', $string);
  1942. if (isset($readMore['1'])) {
  1943. $string = shorten($readMore[0]);
  1944. return $string;
  1945. } else {
  1946. $string = shorten($string, $char);
  1947. return $string;
  1948. }
  1949. } else {
  1950. $string = shorten($string, $char);
  1951. return $string;
  1952. }
  1953. }
  1954. }
  1955. // Shorten the string
  1956. function shorten($string = null, $char = null)
  1957. {
  1958. if(empty($string)) {
  1959. return;
  1960. }
  1961. $string = str_replace('<span class="details">'. config('toc.label') .'</span>', '', $string);
  1962. libxml_use_internal_errors(true);
  1963. $dom = new DOMDocument();
  1964. $dom->loadHTML('<span class="dom-charset"><meta charset="utf8"></span>' . $string);
  1965. $tags_to_remove = array('script', 'style');
  1966. foreach($tags_to_remove as $tag){
  1967. $element = $dom->getElementsByTagName($tag);
  1968. foreach($element as $item){
  1969. $item->parentNode->removeChild($item);
  1970. }
  1971. }
  1972. $string = preg_replace('~<(?:!DOCTYPE|/?(?:html|head|body))[^>]*>\s*~i', '', mb_convert_encoding($dom->saveHTML($dom->documentElement), 'UTF-8'));
  1973. $string = preg_replace('/\s\s+/', ' ', strip_tags($string));
  1974. $string = ltrim(rtrim($string));
  1975. $string = str_replace('<span class="dom-charset"><meta charset="utf8"></span>', '', $string);
  1976. if (!empty($char)) {
  1977. if (mb_strlen($string) > $char) {
  1978. $string = mb_substr($string, 0, $char);
  1979. $string = mb_substr($string, 0, mb_strrpos($string, ' '));
  1980. }
  1981. }
  1982. return $string;
  1983. }
  1984. // Get thumbnail from image and Youtube.
  1985. function get_thumbnail($text, $url = null)
  1986. {
  1987. if (config('img.thumbnail') == 'true') {
  1988. $teaserType = config('teaser.type');
  1989. if (strlen(strip_tags($text)) > config('teaser.char') && $teaserType === 'trimmed') {
  1990. libxml_use_internal_errors(true);
  1991. $default = config('default.thumbnail');
  1992. $dom = new DOMDocument();
  1993. $dom->loadHtml('<meta charset="utf8">' . $text);
  1994. $imgTags = $dom->getElementsByTagName('img');
  1995. $vidTags = $dom->getElementsByTagName('iframe');
  1996. if ($imgTags->length > 0) {
  1997. $imgElement = $imgTags->item(0);
  1998. $imgSource = $imgElement->getAttribute('src');
  1999. if (!empty($url)) {
  2000. return $imgSource;
  2001. } else {
  2002. return '<div class="thumbnail" style="background-image:url(' . $imgSource . ');"></div>';
  2003. }
  2004. } elseif ($vidTags->length > 0) {
  2005. $vidElement = $vidTags->item(0);
  2006. $vidSource = $vidElement->getAttribute('src');
  2007. $fetch = explode("embed/", $vidSource);
  2008. if (isset($fetch[1])) {
  2009. $vidThumb = '//img.youtube.com/vi/' . $fetch[1] . '/default.jpg';
  2010. if (!empty($url)) {
  2011. return $vidThumb;
  2012. } else {
  2013. return '<div class="thumbnail" style="background-image:url(' . $vidThumb . ');"></div>';
  2014. }
  2015. }
  2016. } else {
  2017. if (!empty($default)) {
  2018. if (!empty($url)) {
  2019. return $default;
  2020. } else {
  2021. return '<div class="thumbnail" style="background-image:url(' . $default . ');"></div>';
  2022. }
  2023. }
  2024. }
  2025. } else {
  2026. // Ignore
  2027. }
  2028. }
  2029. }
  2030. // Get image from post and Youtube thumbnail.
  2031. function get_image($text, $width = null, $height = null)
  2032. {
  2033. libxml_use_internal_errors(true);
  2034. $dom = new DOMDocument();
  2035. $dom->loadHtml('<meta charset="utf8">' . $text);
  2036. $imgTags = $dom->getElementsByTagName('img');
  2037. $vidTags = $dom->getElementsByTagName('iframe');
  2038. if ($imgTags->length > 0) {
  2039. $imgElement = $imgTags->item(0);
  2040. $imgSource = $imgElement->getAttribute('src');
  2041. if(is_null($width)) {
  2042. return $imgSource;
  2043. } else {
  2044. return create_thumb($imgSource, $width, $height);
  2045. }
  2046. } elseif ($vidTags->length > 0) {
  2047. $vidElement = $vidTags->item(0);
  2048. $vidSource = $vidElement->getAttribute('src');
  2049. $fetch = explode("embed/", $vidSource);
  2050. if (isset($fetch[1])) {
  2051. $vidThumb = '//img.youtube.com/vi/' . $fetch[1] . '/sddefault.jpg';
  2052. return $vidThumb;
  2053. }
  2054. } else{
  2055. return false;
  2056. }
  2057. }
  2058. // Return edit tab on post
  2059. function tab($p)
  2060. {
  2061. $user = $_SESSION[site_url()]['user'];
  2062. $role = user('role', $user);
  2063. $tab = '';
  2064. if (isset($p->author)) {
  2065. if ($user === $p->author || $role === 'editor' || $role === 'admin') {
  2066. $tab = '<div class="tab"><ul class="nav nav-tabs"><li role="presentation" class="active"><a href="' . $p->url . '">' . i18n('View') .'</a></li><li><a href="' . $p->url . '/edit?destination=post">'. i18n('Edit') .'</a></li></ul></div>';
  2067. }
  2068. } else {
  2069. if ($p->url) {
  2070. if ($role === 'editor' || $role === 'admin') {
  2071. $tab = '<div class="tab"><ul class="nav nav-tabs"><li role="presentation" class="active"><a href="' . $p->url . '">' . i18n('View') .'</a></li><li><a href="' . $p->url . '/edit?destination=post">'. i18n('Edit') .'</a></li></ul></div>';
  2072. }
  2073. }
  2074. }
  2075. return $tab;
  2076. }
  2077. // Social links
  2078. function social($class = null)
  2079. {
  2080. $bluesky = config('social.bluesky');
  2081. $twitter = config('social.twitter');
  2082. $facebook = config('social.facebook');
  2083. $instagram = config('social.instagram');
  2084. $linkedin = config('social.linkedin');
  2085. $github = config('social.github');
  2086. $youtube = config('social.youtube');
  2087. $mastodon = config('social.mastodon');
  2088. $tiktok = config('social.tiktok');
  2089. $rss = site_url() . 'feed/rss';
  2090. $social = '';
  2091. $social .= '<div class="social-logo ' . $class . '">';
  2092. $social .= '<link rel="stylesheet" id="social-logo-style" href="'. site_url() .'system/resources/css/social-logos.css" type="text/css" media="all">';
  2093. if (!empty($bluesky)) {
  2094. $social .= '<a class="social-logo-bluesky" href="' . $bluesky . '" target="_blank" rel="nofollow"><span class="screen-reader-text">Bluesky</span></a>';
  2095. }
  2096. if (!empty($twitter)) {
  2097. $social .= '<a class="social-logo-x" href="' . $twitter . '" target="_blank" rel="nofollow"><span class="screen-reader-text">Twitter</span></a>';
  2098. }
  2099. if (!empty($facebook)) {
  2100. $social .= '<a class="social-logo-facebook" href="' . $facebook . '" target="_blank" rel="nofollow"><span class="screen-reader-text">Facebook</span></a>';
  2101. }
  2102. if (!empty($instagram)) {
  2103. $social .= '<a class="social-logo-instagram" href="' . $instagram . '" target="_blank" rel="nofollow"><span class="screen-reader-text">Instagram</span></a>';
  2104. }
  2105. if (!empty($linkedin)) {
  2106. $social .= '<a class="social-logo-linkedin" href="' . $linkedin . '" target="_blank" rel="nofollow"><span class="screen-reader-text">Linkedin</span></a>';
  2107. }
  2108. if (!empty($github)) {
  2109. $social .= '<a class="social-logo-github" href="' . $github . '" target="_blank" rel="nofollow"><span class="screen-reader-text">Github</span></a>';
  2110. }
  2111. if (!empty($youtube)) {
  2112. $social .= '<a class="social-logo-youtube" href="' . $youtube . '" target="_blank" rel="nofollow"><span class="screen-reader-text">Youtube</span></a>';
  2113. }
  2114. if (!empty($mastodon)) {
  2115. $social .= '<a class="social-logo-mastodon" href="' . $mastodon . '" target="_blank" rel="nofollow"><span class="screen-reader-text">Mastodon</span></a>';
  2116. }
  2117. if (!empty($tiktok)) {
  2118. $social .= '<a class="social-logo-tiktok" href="' . $tiktok . '" target="_blank" rel="nofollow"><span class="screen-reader-text">TikTok</span></a>';
  2119. }
  2120. $social .= '<a class="social-logo-feed" href="' . $rss . '" target="_blank"><span class="screen-reader-text">RSS</span></a>';
  2121. $social .= '</div>';
  2122. return $social;
  2123. }
  2124. // Copyright
  2125. function copyright()
  2126. {
  2127. $blogcp = blog_copyright();
  2128. $credit = i18n('proudly_powered_by') . ' ' . '<a href="http://www.htmly.com" target="_blank" rel="nofollow">HTMLy</a>';
  2129. if (!empty($blogcp)) {
  2130. return $copyright = '<span class="copyright">' . $blogcp . '</span> <span class="credit">' . $credit . '</span>';
  2131. } else {
  2132. return $credit = '<span class="credit">' . $credit . '</span>';
  2133. }
  2134. }
  2135. // Disqus on post.
  2136. function disqus($title = null, $url = null)
  2137. {
  2138. $comment = config('comment.system');
  2139. $disqus = config('disqus.shortname');
  2140. $script = <<<EOF
  2141. <script type="text/javascript">
  2142. var getAbsolutePath = function(href) {
  2143. var link = document.createElement('a');
  2144. link.href = href;
  2145. return link.href;
  2146. };
  2147. var disqus_shortname = '{$disqus}';
  2148. var disqus_title = '{$title}';
  2149. var disqus_url = getAbsolutePath('{$url}');
  2150. (function () {
  2151. var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
  2152. dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
  2153. (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
  2154. })();
  2155. </script>
  2156. EOF;
  2157. if (!empty($disqus) && $comment == 'disqus') {
  2158. return $script;
  2159. }
  2160. }
  2161. // Disqus comment count on teaser
  2162. function disqus_count()
  2163. {
  2164. $comment = config('comment.system');
  2165. $disqus = config('disqus.shortname');
  2166. $script = <<<EOF
  2167. <script type="text/javascript">
  2168. var disqus_shortname = '{$disqus}';
  2169. (function () {
  2170. var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
  2171. dsq.src = '//' + disqus_shortname + '.disqus.com/count.js';
  2172. (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
  2173. })();
  2174. </script>
  2175. EOF;
  2176. if (!empty($disqus) && $comment == 'disqus') {
  2177. return $script;
  2178. }
  2179. }
  2180. // Disqus recent comments
  2181. function recent_comments()
  2182. {
  2183. $comment = config('comment.system');
  2184. $disqus = config('disqus.shortname');
  2185. $script = <<<EOF
  2186. <script type="text/javascript" src="//{$disqus}.disqus.com/recent_comments_widget.js?num_items=5&hide_avatars=0&avatar_size=48&excerpt_length=200&hide_mods=0"></script>
  2187. EOF;
  2188. if (!empty($disqus) && $comment == 'disqus') {
  2189. return $script;
  2190. }
  2191. }
  2192. // Facebook comments
  2193. function facebook()
  2194. {
  2195. $comment = config('comment.system');
  2196. $appid = config('fb.appid');
  2197. $lang = locale_language();
  2198. $script = <<<EOF
  2199. <div id="fb-root"></div>
  2200. <script>(function (d, s, id) {
  2201. var js, fjs = d.getElementsByTagName(s)[0];
  2202. if (d.getElementById(id)) return;
  2203. js = d.createElement(s);
  2204. js.id = id;
  2205. js.src = "//connect.facebook.net/{$lang}/all.js#xfbml=1&appId={$appid}";
  2206. fjs.parentNode.insertBefore(js, fjs);
  2207. }(document, 'script', 'facebook-jssdk'));
  2208. </script>
  2209. <style>.fb-comments, .fb_iframe_widget span, .fb-comments iframe {width: 100%!important;}</style>
  2210. EOF;
  2211. if (!empty($appid) && $comment == 'facebook') {
  2212. return $script;
  2213. }
  2214. }
  2215. // Google Publisher (Google+ page).
  2216. function publisher()
  2217. {
  2218. $publisher = config('google.publisher');
  2219. if (!empty($publisher)) {
  2220. return $publisher;
  2221. }
  2222. }
  2223. // Google Analytics
  2224. function analytics()
  2225. {
  2226. $analytics = config('google.analytics.id');
  2227. $gtag = config('google.gtag.id');
  2228. $script = <<<EOF
  2229. <script>
  2230. (function (i,s,o,g,r,a,m) {i['GoogleAnalyticsObject']=r;i[r]=i[r]||function () {
  2231. (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  2232. m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  2233. })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
  2234. ga('create', '{$analytics}', 'auto');
  2235. ga('send', 'pageview');
  2236. </script>
  2237. EOF;
  2238. $gtagScript = <<<EOF
  2239. <!-- Global site tag (gtag.js) - Google Analytics -->
  2240. <script async src="https://www.googletagmanager.com/gtag/js?id={$gtag}"></script>
  2241. <script>
  2242. window.dataLayer = window.dataLayer || [];
  2243. function gtag(){dataLayer.push(arguments);}
  2244. gtag('js', new Date());
  2245. gtag('config', '{$gtag}');
  2246. </script>
  2247. EOF;
  2248. if (!empty($gtag)) {
  2249. return $gtagScript;
  2250. } elseif (!empty($analytics)) {
  2251. return $script;
  2252. }
  2253. }
  2254. function slashUrl($url)
  2255. {
  2256. return rtrim($url, '/') . '/';
  2257. }
  2258. function parseNodes($nodes, $child = null, $class = null)
  2259. {
  2260. if (empty($child)) {
  2261. $ul = '<ul class="nav navbar-nav '.$class.'">';
  2262. foreach ($nodes as $node) {
  2263. if (isset($node->children)) {
  2264. $ul .= parseNode($node, true);
  2265. } else {
  2266. $ul .= parseNode($node);
  2267. }
  2268. }
  2269. $ul .= '</ul>';
  2270. return $ul;
  2271. } else {
  2272. $ul = '<ul class="subnav dropdown-menu" role="menu">';
  2273. foreach ($nodes as $node) {
  2274. if (isset($node->children)) {
  2275. $ul .= parseNode($node, true);
  2276. } else {
  2277. $ul .= parseNode($node);
  2278. }
  2279. }
  2280. $ul .= '</ul>';
  2281. return $ul;
  2282. }
  2283. }
  2284. function parseNode($node, $child = null)
  2285. {
  2286. $req = strtok($_SERVER["REQUEST_URI"],'?');
  2287. $url = parse_url(slashUrl($node->slug));
  2288. $su = parse_url(site_url());
  2289. $target = !empty($node->target) ? 'target="'.$node->target.'"' : null;
  2290. if (empty($child)) {
  2291. if (isset($url['host']) && isset($su['host'])) {
  2292. if ($url['host'] == $su['host']) {
  2293. if (slashUrl($url['path']) == slashUrl($req)) {
  2294. $li = '<li class="item nav-item active '.$node->class.'">';
  2295. } else {
  2296. $li = '<li class="item nav-item '.$node->class.'">';
  2297. }
  2298. } else {
  2299. $li = '<li class="item nav-item '.$node->class.'">'; // Link out
  2300. }
  2301. } else {
  2302. if (slashUrl($node->slug) == slashUrl($req)) {
  2303. $li = '<li class="item nav-item active '.$node->class.'">';
  2304. } else {
  2305. $li = '<li class="item nav-item '.$node->class.'">';
  2306. }
  2307. }
  2308. $li .= '<a class="nav-link" href="'.htmlspecialchars(slashUrl($node->slug), FILTER_SANITIZE_URL).'" '.$target.'>'.$node->name.'</a>';
  2309. if (isset($node->children)) {
  2310. $li .= parseNodes($node->children, true, null);
  2311. }
  2312. $li .= '</li>';
  2313. return $li;
  2314. } else {
  2315. if (isset($url['host']) && isset($su['host'])) {
  2316. if ($url['host'] == $su['host']) {
  2317. if (slashUrl($url['path']) == slashUrl($req)) {
  2318. $li = '<li class="item nav-item dropdown active '.$node->class.'">';
  2319. } else {
  2320. $li = '<li class="item nav-item dropdown '.$node->class.'">';
  2321. }
  2322. } else {
  2323. $li = '<li class="item nav-item dropdown '.$node->class.'">'; // Link out
  2324. }
  2325. } else {
  2326. if (slashUrl($node->slug) == slashUrl($req)) {
  2327. $li = '<li class="item nav-item dropdown active '.$node->class.'">';
  2328. } else {
  2329. $li = '<li class="item nav-item dropdown '.$node->class.'">';
  2330. }
  2331. }
  2332. $li .= '<a class="nav-link dropdown-toggle" data-toggle="dropdown" data-bs-toggle="dropdown" href="'.htmlspecialchars(slashUrl($node->slug), FILTER_SANITIZE_URL).'" '.$target.'>'.$node->name.'<b class="caret"></b></a>';
  2333. if (isset($node->children)) {
  2334. $li .= parseNodes($node->children, true, null);
  2335. }
  2336. $li .= '</li>';
  2337. return $li;
  2338. }
  2339. }
  2340. // Menu
  2341. function menu($class = null)
  2342. {
  2343. $filename = "content/data/menu.json";
  2344. if (file_exists($filename)) {
  2345. $json = json_decode(file_get_contents('content/data/menu.json', true));
  2346. $nodes = json_decode($json);
  2347. if (empty($nodes)) {
  2348. return get_menu($class);
  2349. } else {
  2350. $html = parseNodes($nodes, null, $class);
  2351. $output = '';
  2352. libxml_use_internal_errors(true);
  2353. $doc = new DOMDocument();
  2354. $doc->loadHTML('<span class="dom-charset"><meta charset="utf8"></span>' . $html);
  2355. $finder = new DOMXPath($doc);
  2356. $elements = $finder->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' dropdown-menu ')]");
  2357. // loop through all <ul> with dropdown-menu class
  2358. foreach ($elements as $element) {
  2359. $nodes = $element->childNodes;
  2360. foreach ($nodes as $node) {
  2361. $class = $node->getAttribute('class');
  2362. if (stripos($class, 'active')) {
  2363. $parentClass = $element->parentNode->getAttribute('class') . ' active';
  2364. $element->parentNode->setAttribute('class', $parentClass);
  2365. }
  2366. }
  2367. }
  2368. $output = preg_replace('~<(?:!DOCTYPE|/?(?:html|head|body))[^>]*>\s*~i', '', mb_convert_encoding($doc->saveHTML($doc->documentElement), 'UTF-8'));
  2369. return str_replace('<span class="dom-charset"><meta charset="utf8"></span>', '', $output);
  2370. }
  2371. } else {
  2372. return get_menu($class);
  2373. }
  2374. }
  2375. // Get the title from file
  2376. function get_title_from_file($v)
  2377. {
  2378. // Get the contents and convert it to HTML
  2379. $content = MarkdownExtra::defaultTransform(file_get_contents($v));
  2380. $filename= pathinfo($v, PATHINFO_FILENAME);
  2381. // Extract the title and body
  2382. return get_content_tag('t', $content, str_replace('-', ' ', $filename));
  2383. }
  2384. // Auto generate menu from static page
  2385. function get_menu($custom = null, $auto = null)
  2386. {
  2387. $posts = get_static_pages();
  2388. $req = $_SERVER['REQUEST_URI'];
  2389. $menu = '';
  2390. if (!empty($posts)) {
  2391. $menu .= '<ul class="nav ' . $custom . '">';
  2392. if (is_null($auto)) {
  2393. if ($req == site_path() . '/' || stripos($req, site_path() . '/?page') !== false) {
  2394. $menu .= '<li class="item nav-item first active"><a class="nav-link" href="' . site_url() . '">' . config('breadcrumb.home') . '</a></li>';
  2395. } else {
  2396. $menu .= '<li class="item nav-item first"><a class="nav-link" href="' . site_url() . '">' . config('breadcrumb.home') . '</a></li>';
  2397. }
  2398. if (config('blog.enable') == 'true' ) {
  2399. if ($req == site_path() . '/' . blog_path() || stripos($req, site_path() . '/' . blog_path() . '?page') !== false) {
  2400. $menu .= '<li class="item nav-item active"><a class="nav-link" href="' . site_url() . blog_path() . '">' . blog_string() . '</a></li>';
  2401. } else {
  2402. $menu .= '<li class="item nav-item"><a class="nav-link" href="' . site_url() . blog_path() . '">' . blog_string() . '</a></li>';
  2403. }
  2404. }
  2405. }
  2406. $i = 0;
  2407. $len = count($posts);
  2408. foreach ($posts as $index => $v) {
  2409. if ($i == $len - 1) {
  2410. $class = 'item nav-item last';
  2411. } else {
  2412. $class = 'item nav-item';
  2413. }
  2414. $i++;
  2415. // Filename string
  2416. $fn = explode('.', $v['filename']);
  2417. if (isset($fn[1])) {
  2418. $filename= $fn[1];
  2419. } else {
  2420. $filename= $v['filename'];
  2421. }
  2422. $url = site_url() . $filename;
  2423. $parent_file = $v['dirname'] . '/' . $v['basename'];
  2424. $title = get_title_from_file($parent_file);
  2425. if ($req == site_path() . "/" . $filename || stripos($req, site_path() . "/" . $filename) !== false) {
  2426. $active = ' active';
  2427. $reqBase = '';
  2428. } else {
  2429. $active = '';
  2430. }
  2431. $subPages = get_static_subpages($filename);
  2432. if (!empty($subPages)) {
  2433. $menu .= '<li class="' . $class . $active .' dropdown">';
  2434. $menu .= '<a class="nav-link dropdown-toggle" data-toggle="dropdown" data-bs-toggle="dropdown" href="' . $url . '">' . ucwords($title) . '<b class="caret"></b></a>';
  2435. $menu .= '<ul class="subnav dropdown-menu" role="menu">';
  2436. $iSub = 0;
  2437. $countSub = count($subPages);
  2438. foreach ($subPages as $index => $sp) {
  2439. $classSub = "item nav-item";
  2440. if ($iSub == 0) {
  2441. $classSub .= " first";
  2442. }
  2443. if ($iSub == $countSub - 1) {
  2444. $classSub .= " last";
  2445. }
  2446. $bs = explode('.', $sp['filename']);
  2447. if (isset($bs[1])) {
  2448. $baseSub = $bs[1];
  2449. } else {
  2450. $baseSub= $sp['filename'];
  2451. }
  2452. $child_file = $sp['dirname'] . '/' . $sp['basename'];
  2453. if ($req == site_path() . "/" . $filename . "/" . $baseSub) {
  2454. $classSub .= ' active';
  2455. }
  2456. $urlSub = $url . "/" . $baseSub;
  2457. $menu .= '<li class="' . $classSub . '"><a class="nav-link" href="' . $urlSub . '">' . get_title_from_file($child_file) . '</a></li>';
  2458. $iSub++;
  2459. }
  2460. $menu .= '</ul>';
  2461. } else {
  2462. $menu .= '<li class="' . $class . $active .'">';
  2463. $menu .= '<a class="nav-link" href="' . $url . '">' . ucwords($title) . '</a>';
  2464. }
  2465. $menu .= '</li>';
  2466. }
  2467. $menu .='</ul>';
  2468. return $menu;
  2469. } else {
  2470. $menu .= '<ul class="nav ' . $custom . '">';
  2471. if ($req == site_path() . '/') {
  2472. $menu .= '<li class="item nav-item first active"><a class="nav-link" href="' . site_url() . '">' . config('breadcrumb.home') . '</a></li>';
  2473. } else {
  2474. $menu .= '<li class="item nav-item first"><a class="nav-link" href="' . site_url() . '">' . config('breadcrumb.home') . '</a></li>';
  2475. }
  2476. if (config('blog.enable') == 'true' ) {
  2477. if ($req == site_path() . '/' . blog_path() || stripos($req, site_path() . '/'. blog_path() .'?page') !== false) {
  2478. $menu .= '<li class="item nav-item active"><a class="nav-link" href="' . site_url() . blog_path() . '">' . blog_string() . '</a></li>';
  2479. } else {
  2480. $menu .= '<li class="item nav-item"><a class="nav-link" href="' . site_url() . blog_path() . '">' . blog_string() . '</a></li>';
  2481. }
  2482. }
  2483. $menu .= '</ul>';
  2484. return $menu;
  2485. }
  2486. }
  2487. // Search form
  2488. function search($text = null)
  2489. {
  2490. if(!empty($text)) {
  2491. echo <<<EOF
  2492. <form id="search-form" method="get">
  2493. <input type="text" class="search-input" name="search" value="{$text}" onfocus="if (this.value == '{$text}') {this.value = '';}" onblur="if (this.value == '') {this.value = '{$text}';}">
  2494. <input type="submit" value="{$text}" class="search-button">
  2495. </form>
  2496. EOF;
  2497. } else {
  2498. $search = i18n('Search');
  2499. echo <<<EOF
  2500. <form id="search-form" method="get">
  2501. <input type="text" class="search-input" name="search" value="{$search}" onfocus="if (this.value == '{$search}') {this.value = '';}" onblur="if (this.value == '') {this.value = '{$search}';}">
  2502. <input type="submit" value="{$search}" class="search-button">
  2503. </form>
  2504. EOF;
  2505. }
  2506. if (isset($_GET['search'])) {
  2507. $search = _h($_GET['search']);
  2508. $url = site_url() . 'search/' . remove_accent($search);
  2509. header("Location: $url");
  2510. }
  2511. }
  2512. // The not found error
  2513. function not_found($request = null)
  2514. {
  2515. if (!config('views.root')) die('HTMLy is not installed!');
  2516. $vroot = rtrim(config('views.root'), '/');
  2517. $lt = $vroot . '/layout--404.html.php';
  2518. if (file_exists($lt)) {
  2519. $layout = 'layout--404';
  2520. } else {
  2521. $layout = '';
  2522. }
  2523. header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found");
  2524. render('404', array(
  2525. 'title' => generate_title('is_default', i18n('This_page_doesnt_exist')),
  2526. 'description' => i18n('This_page_doesnt_exist'),
  2527. 'canonical' => site_url(),
  2528. 'metatags' => generate_meta(null, null),
  2529. 'breadcrumb' => '<a href="' . site_url() . '">' . config('breadcrumb.home') . '</a> &#187; ' . i18n('This_page_doesnt_exist'),
  2530. 'bodyclass' => 'error-404',
  2531. 'is_404' => true,
  2532. ), $layout);
  2533. die();
  2534. }
  2535. // Turn an array of posts into an RSS feed
  2536. function generate_rss($posts, $data = null)
  2537. {
  2538. $feed = new Feed();
  2539. $channel = new Channel();
  2540. $rssLength = config('rss.char');
  2541. $data = $data;
  2542. $rssDesc = config('rss.description');
  2543. if (is_null($data)) {
  2544. $channel
  2545. ->title(blog_title())
  2546. ->description(blog_description())
  2547. ->url(site_url())
  2548. ->appendTo($feed);
  2549. } else {
  2550. $channel
  2551. ->title($data->title)
  2552. ->description(strip_tags($data->body))
  2553. ->url($data->url)
  2554. ->appendTo($feed);
  2555. }
  2556. if ($posts) {
  2557. foreach ($posts as $p) {
  2558. $img = get_image($p->body);
  2559. if ($rssDesc == "meta") {
  2560. if (!empty($rssLength)) {
  2561. $body = shorten($p->description, $rssLength);
  2562. } else {
  2563. $body = $p->description;
  2564. }
  2565. } else {
  2566. if (!empty($rssLength)) {
  2567. $body = shorten($p->body, $rssLength);
  2568. } else {
  2569. $body = $p->body;
  2570. }
  2571. }
  2572. $item = new Item();
  2573. $item
  2574. ->category(strip_tags($p->category));
  2575. $item
  2576. ->title($p->title)
  2577. ->pubDate($p->date)
  2578. ->description($body)
  2579. ->url($p->url)
  2580. ->appendTo($channel);
  2581. if (!empty($p->image)) {
  2582. $item->enclosure($p->image, 0, "image/" . pathinfo($p->image, PATHINFO_EXTENSION));
  2583. } elseif (!empty($img)) {
  2584. $item->enclosure($img, 0, "image/" . pathinfo($img, PATHINFO_EXTENSION));
  2585. }
  2586. }
  2587. }
  2588. return $feed;
  2589. }
  2590. // Return post, archive url for sitemap
  2591. function sitemap_post_path($posts, $page = 1, $perpage = 0)
  2592. {
  2593. if (empty($posts)) {
  2594. $posts = get_blog_posts();
  2595. }
  2596. krsort($posts);
  2597. $tmp = array();
  2598. $posts = array_slice($posts, ($page - 1) * $perpage, $perpage);
  2599. foreach ($posts as $index => $v) {
  2600. $post = new stdClass;
  2601. $filepath = $v['dirname'] . '/' . $v['basename'];
  2602. // Extract the date
  2603. $arr = explode('_', $v['basename']);
  2604. // dirname string
  2605. $dirname = $v['dirname'];
  2606. // Author string
  2607. $str = explode('/', $dirname);
  2608. $author = $str[1];
  2609. $post->authorUrl = site_url() . 'author/' . $author;
  2610. $dt = str_replace($dirname, '', $arr[0]);
  2611. $t = str_replace('-', '', $dt);
  2612. $time = new DateTime($t);
  2613. $timestamp = $time->format("Y-m-d H:i:s");
  2614. // The post date
  2615. $post->date = strtotime($timestamp);
  2616. $post->lastMod = strtotime(date('Y-m-d H:i:s', filemtime($filepath)));
  2617. // The archive per month
  2618. $post->archivemonth = site_url() . 'archive/' . date('Y-m', $post->date);
  2619. // The archive per year
  2620. $post->archiveyear = site_url() . 'archive/' . date('Y', $post->date);
  2621. // The post URL
  2622. if (permalink_type() == 'default') {
  2623. $post->url = site_url() . date('Y/m', $post->date) . '/' . str_replace('.md', '', $arr[2]);
  2624. } else {
  2625. $post->url = site_url() . permalink_type() . '/' . str_replace('.md', '', $arr[2]);
  2626. }
  2627. $tmp[] = $post;
  2628. }
  2629. return $tmp;
  2630. }
  2631. // Return static page path for sitemap
  2632. function sitemap_page_path()
  2633. {
  2634. $posts = get_static_pages();
  2635. $tmp = array();
  2636. if (!empty($posts)) {
  2637. foreach ($posts as $index => $v) {
  2638. $post = new stdClass;
  2639. $fn = explode('.', $v['filename']);
  2640. if (isset($fn[1])) {
  2641. $filename = $fn[1];
  2642. } else {
  2643. $filename= $v['filename'];
  2644. }
  2645. $file = $v['dirname'] . '/' . $v['basename'];
  2646. $post->url = site_url() . $filename;
  2647. $post->lastMod = strtotime(date('Y-m-d H:i:s', filemtime($file)));
  2648. $tmp[] = $post;
  2649. $subPages = get_static_subpages($filename);
  2650. foreach ($subPages as $sIndex => $sp) {
  2651. $subpost = new stdClass;
  2652. $bs = explode('.', $sp['filename']);
  2653. if (isset($bs[1])) {
  2654. $baseSub = $bs[1];
  2655. } else {
  2656. $baseSub = $sp['filename'];
  2657. }
  2658. $urlSub = $filename . '/' . $baseSub;
  2659. $subfile = $sp['dirname'] . '/' . $sp['basename'];
  2660. $subpost->url = site_url() . $urlSub;
  2661. $subpost->lastMod = strtotime(date('Y-m-d H:i:s', filemtime($subfile)));
  2662. $tmp[] = $subpost;
  2663. }
  2664. }
  2665. }
  2666. return $tmp;
  2667. }
  2668. // Generate sitemap.xml.
  2669. function generate_sitemap($str)
  2670. {
  2671. $default_priority = '0.5';
  2672. $map = '';
  2673. header('X-Robots-Tag: noindex');
  2674. $map .= '<?xml version="1.0" encoding="UTF-8"?>';
  2675. if ($str == 'index.xml') {
  2676. $map .= '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
  2677. if (config('sitemap.priority.base') !== '-1') {
  2678. $map .= '<sitemap><loc>' . site_url() . 'sitemap.base.xml</loc></sitemap>';
  2679. }
  2680. if (config('sitemap.priority.post') !== '-1') {
  2681. $map .= '<sitemap><loc>' . site_url() . 'sitemap.post.xml</loc></sitemap>';
  2682. }
  2683. if (config('sitemap.priority.static') !== '-1') {
  2684. $map .= '<sitemap><loc>' . site_url() . 'sitemap.static.xml</loc></sitemap>';
  2685. }
  2686. if (config('sitemap.priority.category') !== '-1') {
  2687. $map .= '<sitemap><loc>' . site_url() . 'sitemap.category.xml</loc></sitemap>';
  2688. }
  2689. if (config('sitemap.priority.tag') !== '-1') {
  2690. $map .= '<sitemap><loc>' . site_url() . 'sitemap.tag.xml</loc></sitemap>';
  2691. }
  2692. if (config('sitemap.priority.archiveDay') !== '-1' || config('sitemap.priority.archiveMonth') !== '-1' || config('sitemap.priority.archiveYear') !== '-1') {
  2693. $map .= '<sitemap><loc>' . site_url() . 'sitemap.archive.xml</loc></sitemap>';
  2694. }
  2695. if (config('sitemap.priority.author') !== '-1') {
  2696. $map .= '<sitemap><loc>' . site_url() . 'sitemap.author.xml</loc></sitemap>';
  2697. }
  2698. if (config('sitemap.priority.type') !== '-1') {
  2699. $map .= '<sitemap><loc>' . site_url() . 'sitemap.type.xml</loc></sitemap>';
  2700. }
  2701. $map .= '</sitemapindex>';
  2702. } elseif ($str == 'base.xml') {
  2703. $priority = (config('sitemap.priority.base')) ? config('sitemap.priority.base') : '1.0';
  2704. $map .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
  2705. if ($priority !== '-1') {
  2706. $map .= '<url><loc>' . site_url() . '</loc><priority>' . $priority . '</priority></url>';
  2707. if (config('blog.enable') === 'true') {
  2708. $map .= '<url><loc>' . site_url() . blog_path() .'</loc><priority>' . $priority . '</priority></url>';
  2709. }
  2710. }
  2711. $map .= '</urlset>';
  2712. } elseif (strpos($str, 'post.') !== false ) {
  2713. if ($str == 'post.xml') {
  2714. $map .= '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
  2715. $totalPosts = array();
  2716. $totalPosts = get_blog_posts();
  2717. $total = count($totalPosts);
  2718. $totalPage = ceil($total / 500);
  2719. for ($i = 1; $i <= $totalPage; $i++) {
  2720. $map .= '<sitemap><loc>' . site_url() . 'sitemap.post.'. $i .'.xml</loc></sitemap>';
  2721. }
  2722. $map .= '</sitemapindex>';
  2723. } else {
  2724. $priority = (config('sitemap.priority.post')) ? config('sitemap.priority.post') : $default_priority;
  2725. $posts = array();
  2726. $arr = explode('.', $str);
  2727. if ($priority !== '-1') {
  2728. $posts = sitemap_post_path(null, $arr[1], 500);
  2729. }
  2730. $map .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
  2731. foreach ($posts as $p) {
  2732. $map .= '<url><loc>' . $p->url . '</loc><priority>' . $priority . '</priority><lastmod>' . date('Y-m-d\TH:i:sP', $p->lastMod) . '</lastmod></url>';
  2733. }
  2734. $map .= '</urlset>';
  2735. }
  2736. } elseif ($str == 'static.xml') {
  2737. $priority = (config('sitemap.priority.static')) ? config('sitemap.priority.static') : $default_priority;
  2738. $posts = array();
  2739. if ($priority !== '-1') {
  2740. $posts = sitemap_page_path();
  2741. }
  2742. $map .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
  2743. foreach ($posts as $p) {
  2744. $map .= '<url><loc>' . $p->url . '</loc><priority>' . $priority . '</priority><lastmod>' . date('Y-m-d\TH:i:sP', $p->lastMod) . '</lastmod></url>';
  2745. }
  2746. $map .= '</urlset>';
  2747. } elseif ($str == 'tag.xml') {
  2748. $priority = (config('sitemap.priority.tag')) ? config('sitemap.priority.tag') : $default_priority;
  2749. $posts = array();
  2750. if ($priority !== '-1') {
  2751. $posts = get_blog_posts();
  2752. }
  2753. $tags = array();
  2754. $map .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
  2755. if($posts) {
  2756. foreach ($posts as $index => $v) {
  2757. $arr = explode('_', $v['filename']);
  2758. $data = $arr[1];
  2759. $mtag = explode(',', $data);
  2760. foreach ($mtag as $etag) {
  2761. $tags[] = strtolower($etag);
  2762. }
  2763. }
  2764. foreach ($tags as $t) {
  2765. $tag[] = site_url() . 'tag/' . strtolower($t);
  2766. }
  2767. if (isset($tag)) {
  2768. $tag = array_unique($tag, SORT_REGULAR);
  2769. foreach ($tag as $t) {
  2770. $map .= '<url><loc>' . $t . '</loc><priority>' . $priority . '</priority></url>';
  2771. }
  2772. }
  2773. }
  2774. $map .= '</urlset>';
  2775. } elseif ($str == 'archive.xml') {
  2776. $priorityMonth = (config('sitemap.priority.archiveMonth')) ? config('sitemap.priority.archiveMonth') : $default_priority;
  2777. $priorityYear = (config('sitemap.priority.archiveYear')) ? config('sitemap.priority.archiveYear') : $default_priority;
  2778. $posts = sitemap_post_path(null, 1, null);
  2779. $month = array();
  2780. $year = array();
  2781. foreach ($posts as $p) {
  2782. $month[] = $p->archivemonth;
  2783. $year[] = $p->archiveyear;
  2784. }
  2785. $month = array_unique($month, SORT_REGULAR);
  2786. $year = array_unique($year, SORT_REGULAR);
  2787. $map .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
  2788. if ($priorityYear !== '-1') {
  2789. foreach ($year as $y) {
  2790. $map .= '<url><loc>' . $y . '</loc><priority>' . $priorityYear . '</priority></url>';
  2791. }
  2792. }
  2793. if ($priorityMonth !== '-1') {
  2794. foreach ($month as $m) {
  2795. $map .= '<url><loc>' . $m . '</loc><priority>' . $priorityMonth . '</priority></url>';
  2796. }
  2797. }
  2798. $map .= '</urlset>';
  2799. } elseif ($str == 'author.xml') {
  2800. $priority = (config('sitemap.priority.author')) ? config('sitemap.priority.author') : $default_priority;
  2801. $author = array();
  2802. if ($priority !== '-1') {
  2803. $posts = sitemap_post_path(null, 1, null);
  2804. foreach ($posts as $p) {
  2805. $author[] = $p->authorUrl;
  2806. }
  2807. $author = array_unique($author, SORT_REGULAR);
  2808. }
  2809. $map .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
  2810. if ($priority !== '-1') {
  2811. foreach ($author as $a) {
  2812. $map .= '<url><loc>' . $a . '</loc><priority>' . $priority . '</priority></url>';
  2813. }
  2814. }
  2815. $map .= '</urlset>';
  2816. } elseif ($str == 'category.xml') {
  2817. $priority = (config('sitemap.priority.category')) ? config('sitemap.priority.category') : $default_priority;
  2818. $posts = array();
  2819. if ($priority !== '-1') {
  2820. $posts = get_blog_posts();
  2821. }
  2822. $cats = array();
  2823. $map .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
  2824. if($posts) {
  2825. foreach ($posts as $index => $v) {
  2826. $dirname = $v['dirname'];
  2827. $str = explode('/', $dirname);
  2828. $cats[] = $str[3];
  2829. }
  2830. foreach ($cats as $c) {
  2831. $cat[] = site_url() . 'category/' . strtolower($c);
  2832. }
  2833. if (isset($cat)) {
  2834. $cat = array_unique($cat, SORT_REGULAR);
  2835. foreach ($cat as $c) {
  2836. $map .= '<url><loc>' . $c . '</loc><priority>' . $priority . '</priority></url>';
  2837. }
  2838. }
  2839. }
  2840. $map .= '</urlset>';
  2841. } elseif ($str == 'type.xml') {
  2842. $priority = (config('sitemap.priority.type')) ? config('sitemap.priority.type') : $default_priority;
  2843. $posts = array();
  2844. if ($priority !== '-1') {
  2845. $posts = get_blog_posts();
  2846. }
  2847. $cats = array();
  2848. $map .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
  2849. if($posts) {
  2850. foreach ($posts as $index => $v) {
  2851. $dirname = $v['dirname'];
  2852. $str = explode('/', $dirname);
  2853. $types[] = $str[4];
  2854. }
  2855. foreach ($types as $t) {
  2856. $type[] = site_url() . 'type/' . strtolower($t);
  2857. }
  2858. if (isset($type)) {
  2859. $type = array_unique($type, SORT_REGULAR);
  2860. foreach ($type as $t) {
  2861. $map .= '<url><loc>' . $t . '</loc><priority>' . $priority . '</priority></url>';
  2862. }
  2863. }
  2864. }
  2865. $map .= '</urlset>';
  2866. }
  2867. echo $map;
  2868. }
  2869. // Function to generate OPML file
  2870. function generate_opml()
  2871. {
  2872. $opml_data = array(
  2873. 'head' => array(
  2874. 'title' => blog_title() . ' OPML File',
  2875. 'ownerName' => blog_title(),
  2876. 'ownerId' => site_url()
  2877. ),
  2878. 'body' => array(
  2879. array(
  2880. 'text' => blog_title(),
  2881. 'description' => blog_description(),
  2882. 'htmlUrl' => site_url(),
  2883. 'language' => 'unknown',
  2884. 'title' => blog_title(),
  2885. 'type' => 'rss',
  2886. 'version' => 'RSS2',
  2887. 'xmlUrl' => site_url() . 'feed/rss'
  2888. )
  2889. )
  2890. );
  2891. $opml = new opml($opml_data);
  2892. return $opml->render();
  2893. }
  2894. // Turn an array of posts into a JSON
  2895. function generate_json($posts)
  2896. {
  2897. return json_encode($posts);
  2898. }
  2899. // TRUE if the current page is an index page like frontpage, tag index, archive index and search index.
  2900. function is_index()
  2901. {
  2902. if (blog_path() == permalink_type()) {
  2903. $req = rtrim(strtok($_SERVER["REQUEST_URI"], '?'), '/') . '/';
  2904. $in = explode('/' . blog_path(), $req);
  2905. if (isset($in[1])) {
  2906. if ($in[1] == '/') {
  2907. return true;
  2908. }
  2909. }
  2910. if (stripos($req, '/category/') !== false || stripos($req, '/archive/') !== false || stripos($req, '/tag/') !== false || stripos($req, '/search/') !== false || stripos($req, '/type/') !== false || $req == site_path() . '/') {
  2911. return true;
  2912. } else {
  2913. return false;
  2914. }
  2915. } else {
  2916. $req = strtok($_SERVER["REQUEST_URI"], '?');
  2917. if (stripos($req, '/category/') !== false || stripos($req, '/archive/') !== false || stripos($req, '/tag/') !== false || stripos($req, '/search/') !== false || stripos($req, '/type/') !== false || stripos($req, '/' . blog_path()) !== false || $req == site_path() . '/') {
  2918. return true;
  2919. } else {
  2920. return false;
  2921. }
  2922. }
  2923. }
  2924. // Return post permalink type
  2925. function permalink_type()
  2926. {
  2927. $permalink = config('permalink.type');
  2928. if (!is_null($permalink) && !empty($permalink)) {
  2929. return strtolower(str_replace('/', '', $permalink));
  2930. }
  2931. return 'default';
  2932. }
  2933. // Return blog path index
  2934. function blog_path()
  2935. {
  2936. $path = config('blog.path');
  2937. if (!is_null($path) && !empty($path)) {
  2938. return strtolower(str_replace('/', '', $path));
  2939. }
  2940. return 'blog';
  2941. }
  2942. // Return blog string
  2943. function blog_string()
  2944. {
  2945. $string = config('blog.string');
  2946. if (!is_null($string) && !empty($string)) {
  2947. return safe_html($string);
  2948. }
  2949. return 'Blog';
  2950. }
  2951. // Return blog title
  2952. function blog_title()
  2953. {
  2954. return safe_html(config('blog.title'));
  2955. }
  2956. // Return blog tagline
  2957. function blog_tagline()
  2958. {
  2959. return safe_html(config('blog.tagline'));
  2960. }
  2961. // Return blog description
  2962. function blog_description()
  2963. {
  2964. return config('blog.description');
  2965. }
  2966. // Return blog copyright
  2967. function blog_copyright()
  2968. {
  2969. return config('blog.copyright');
  2970. }
  2971. // Return blog language
  2972. function blog_language()
  2973. {
  2974. $lang = config('language');
  2975. if (!empty($lang)) {
  2976. $exp = explode('_', $lang);
  2977. return $exp[0] . '-' . $exp[1];
  2978. }
  2979. return 'en-US';
  2980. }
  2981. // Return locale language
  2982. function locale_language()
  2983. {
  2984. $lang = config('language');
  2985. if (!empty($lang)) {
  2986. $exp = explode('_', $lang);
  2987. return $exp[0] . '_' . $exp[1];
  2988. }
  2989. return 'en_US';
  2990. }
  2991. // Output head contents
  2992. function head_contents()
  2993. {
  2994. $output = '';
  2995. $google_wmt_id = config('google.wmt.id');
  2996. $bing_wmt_id = config('bing.wmt.id');
  2997. if (config('show.version') !== 'false') {
  2998. $version = 'HTMLy ' . constant('HTMLY_VERSION');
  2999. } else {
  3000. $version = 'HTMLy';
  3001. }
  3002. $favicon = config('favicon.image');
  3003. if (empty($favicon)) {
  3004. $favicon = '<link rel="icon" type="image/png" href="' . site_url() . 'favicon.png" />' . "\n";
  3005. } else {
  3006. $favicon = '<link rel="icon" type="image/'. pathinfo($favicon, PATHINFO_EXTENSION) .'" href="' . $favicon . '" />' . "\n";
  3007. }
  3008. $output .= '<meta charset="utf-8" />' . "\n";
  3009. $output .= '<meta http-equiv="X-UA-Compatible" content="IE=edge" />' . "\n";
  3010. $output .= '<meta name="viewport" content="width=device-width, initial-scale=1" />' . "\n";
  3011. $output .= '<meta name="generator" content="' . $version . '" />' . "\n";
  3012. $output .= $favicon;
  3013. $output .= '<link rel="sitemap" href="' . site_url() . 'sitemap.xml" />' . "\n";
  3014. $output .= '<link rel="alternate" type="application/rss+xml" title="' . safe_html(blog_title()) . ' Feed" href="' . site_url() . 'feed/rss" />' . "\n";
  3015. if (!empty($google_wmt_id)) {
  3016. $output .= '<meta name="google-site-verification" content="' . $google_wmt_id . '" />' . "\n";
  3017. }
  3018. if (!empty($bing_wmt_id)) {
  3019. $output .= '<meta name="msvalidate.01" content="' . $bing_wmt_id . '" />' . "\n";
  3020. }
  3021. return $output;
  3022. }
  3023. // File cache
  3024. function file_cache($request)
  3025. {
  3026. if (config('cache.off') == 'true') return;
  3027. $hour = config('cache.expiration');
  3028. if (empty($hour)) {
  3029. $hour = 6;
  3030. }
  3031. $now = time();
  3032. $c = str_replace('/', '#', str_replace('?', '~', rawurldecode($request)));
  3033. $cachefile = 'cache/page/' . $c . '.cache';
  3034. if (file_exists($cachefile)) {
  3035. if ($now - filemtime($cachefile) >= 60 * 60 * $hour) {
  3036. unlink($cachefile);
  3037. } else {
  3038. header('Content-type: text/html; charset=utf-8');
  3039. readfile($cachefile);
  3040. die;
  3041. }
  3042. }
  3043. }
  3044. // Add page views count
  3045. function add_view($page)
  3046. {
  3047. $dir = 'content/data/';
  3048. if (!is_dir($dir)) {
  3049. mkdir($dir, 0775, true);
  3050. }
  3051. $filename = "content/data/views.json";
  3052. $views = array();
  3053. if (file_exists($filename)) {
  3054. $views = json_decode(file_get_data($filename), true);
  3055. }
  3056. if (isset($views['flock_fail'])) {
  3057. return;
  3058. } else {
  3059. if (isset($views[$page])) {
  3060. $views[$page]++;
  3061. save_json_pretty($filename, $views);
  3062. } else {
  3063. $views[$page] = 1;
  3064. save_json_pretty($filename, $views);
  3065. }
  3066. }
  3067. }
  3068. // Get the page views count
  3069. function get_views($page, $views = null)
  3070. {
  3071. $filename = "content/data/views.json";
  3072. if (is_null($views)) {
  3073. if (file_exists($filename)) {
  3074. $views = json_decode(file_get_contents($filename), true);
  3075. }
  3076. if (isset($views[$page])) {
  3077. return $views[$page];
  3078. }
  3079. } else {
  3080. if (isset($views[$page])) {
  3081. return $views[$page];
  3082. }
  3083. }
  3084. return -1;
  3085. }
  3086. // Get tag inside the markdown files
  3087. function get_content_tag($tag, $string, $alt = null)
  3088. {
  3089. $reg = '/\<!--' . $tag . '(.+)' . $tag . '--\>/';
  3090. $ary = array();
  3091. if (preg_match($reg, $string, $ary)) {
  3092. if (isset($ary[1])) {
  3093. $result = trim($ary[1]);
  3094. if (!empty($result)) {
  3095. return $result;
  3096. }
  3097. }
  3098. }
  3099. return $alt;
  3100. }
  3101. // Strip html comment
  3102. function remove_html_comments($content)
  3103. {
  3104. $patterns = array('/(\s|)<!--(?!(toc|more)-->).*-->(\s|)/');
  3105. return preg_replace($patterns, '', $content);
  3106. }
  3107. function get_field($key, $object = null)
  3108. {
  3109. if (is_null($object)) {
  3110. return false;
  3111. }
  3112. return (get_content_tag($key, $object));
  3113. }
  3114. // Google recaptcha
  3115. function isCaptcha($reCaptchaResponse)
  3116. {
  3117. $url = "https://www.google.com/recaptcha/api/siteverify";
  3118. $options = array(
  3119. "secret" => config("login.protect.private"),
  3120. "response" => $reCaptchaResponse,
  3121. "remoteip" => $_SERVER['REMOTE_ADDR'],
  3122. );
  3123. $fileContent = @file_get_contents($url . "?" . http_build_query($options));
  3124. if ($fileContent === false) {
  3125. return false;
  3126. }
  3127. $json = json_decode($fileContent, true);
  3128. if ($json == false) {
  3129. return false;
  3130. }
  3131. return ($json['success']);
  3132. }
  3133. // Cloudflare Turnstile
  3134. function isTurnstile($turnstileResponse)
  3135. {
  3136. $public = config("login.protect.public");
  3137. $private = config("login.protect.private");
  3138. $ip = $_SERVER['REMOTE_ADDR'];
  3139. $url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
  3140. $data = array('secret' => $private, 'response' => $turnstileResponse, 'remoteip' => $ip);
  3141. $query = http_build_query($data);
  3142. $options = array(
  3143. 'http' => array(
  3144. 'header' => "Content-Type: application/x-www-form-urlencoded\r\n".
  3145. "Content-Length: ".strlen($query)."\r\n".
  3146. "User-Agent:HTMLy/1.0\r\n",
  3147. 'method' => "POST",
  3148. 'content' => $query,
  3149. )
  3150. );
  3151. $stream = stream_context_create($options);
  3152. $fileContent = file_get_contents($url, false, $stream);
  3153. if ($fileContent === false) {
  3154. return false;
  3155. }
  3156. $json = json_decode($fileContent, true);
  3157. if ($json == false) {
  3158. return false;
  3159. }
  3160. return ($json['success']);
  3161. }
  3162. // Get video ID
  3163. function get_video_id($url)
  3164. {
  3165. if(empty($url)) {
  3166. return;
  3167. }
  3168. $link = parse_url($url);
  3169. if(!isset($link['host'])) {
  3170. return $url;
  3171. }
  3172. if (stripos($link['host'], 'youtube.com') !== false || stripos($link['host'], 'youtu.be') !== false) {
  3173. preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match);
  3174. return $match[1];
  3175. } elseif (stripos($link['host'], 'vimeo.com') !== false) {
  3176. preg_match('%^https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)(?:[?]?.*)$%im', $url, $match);
  3177. return $match[3];
  3178. } else {
  3179. return $url;
  3180. }
  3181. }
  3182. // translate tag to i18n
  3183. function tag_i18n($tag)
  3184. {
  3185. static $tags = array();
  3186. $filename = "content/data/tags.lang";
  3187. if (file_exists($filename)) {
  3188. $tags = unserialize(file_get_contents($filename));
  3189. }
  3190. if (isset($tags[$tag])) {
  3191. return $tags[$tag];
  3192. }
  3193. return $tag;
  3194. }
  3195. // return html safe string
  3196. function safe_html($string)
  3197. {
  3198. $string = htmlspecialchars($string, ENT_QUOTES);
  3199. $string = preg_replace('/\r\n|\r|\n/', ' ', $string);
  3200. $string = preg_replace('/\s\s+/', ' ', $string);
  3201. $string = ltrim(rtrim($string));
  3202. return $string;
  3203. }
  3204. // Replace href
  3205. function replace_href($string, $tag, $class, $url)
  3206. {
  3207. libxml_use_internal_errors(true);
  3208. // Load the HTML in DOM
  3209. $doc = new DOMDocument();
  3210. $doc->loadHTML('<span class="dom-charset"><meta charset="utf8"></span>' . $string);
  3211. $output = '';
  3212. // Then select all anchor tags
  3213. $all_anchor_tags = $doc->getElementsByTagName($tag);
  3214. foreach ($all_anchor_tags as $_tag) {
  3215. if ($_tag->getAttribute('class') == $class) {
  3216. // If match class get the href value
  3217. $old = $_tag->getAttribute('href');
  3218. $new = $_tag->setAttribute('href', $url . mb_convert_encoding($old, 'UTF-8'));
  3219. }
  3220. }
  3221. $output = preg_replace('~<(?:!DOCTYPE|/?(?:html|head|body))[^>]*>\s*~i', '', mb_convert_encoding($doc->saveHTML($doc->documentElement), 'UTF-8'));
  3222. return str_replace('<span class="dom-charset"><meta charset="utf8"></span>', '', $output);
  3223. }
  3224. // Format the date
  3225. function format_date($date, $dateFormat = null)
  3226. {
  3227. if (empty($dateFormat)) {
  3228. $dateFormat = config('date.format');
  3229. }
  3230. if (extension_loaded('intl')) {
  3231. $format_map = array('s' => 'ss', 'i' => 'mm', 'H' => 'HH', 'G' => 'H', 'd' => 'dd', 'j' => 'd', 'D' => 'EE', 'l' => 'EEEE', 'm' => 'MM', 'M' => 'MMM', 'F' => 'MMMM', 'Y' => 'yyyy');
  3232. $intlFormat = strtr($dateFormat, $format_map);
  3233. $formatter = new IntlDateFormatter(locale_language(), IntlDateFormatter::NONE, IntlDateFormatter::NONE, config('timezone'), IntlDateFormatter::GREGORIAN, $intlFormat);
  3234. return $formatter->format($date);
  3235. } else {
  3236. return date($dateFormat, $date);
  3237. }
  3238. }
  3239. // Publish scheduled post
  3240. function publish_scheduled()
  3241. {
  3242. $posts = get_scheduled_posts();
  3243. if (!empty($posts)) {
  3244. foreach ($posts as $index => $v) {
  3245. $str = explode('_', $v['basename']);
  3246. $old = $v['dirname'] . '/' . $v['basename'];
  3247. $new = dirname($v['dirname']) . '/' . $v['basename'];
  3248. $t = str_replace('-', '', $str[0]);
  3249. $time = new DateTime($t);
  3250. $timestamp = $time->format("Y m d H:i:s");
  3251. if (date('Y m d H:i:s') >= $timestamp) {
  3252. rename($old, $new);
  3253. rebuilt_cache('all');
  3254. clear_cache();
  3255. }
  3256. }
  3257. }
  3258. }
  3259. // Insert toc
  3260. function insert_toc($id, $part_1 = null, $part_2 = null)
  3261. {
  3262. $state = config('toc.state');
  3263. if ($state !== 'open') {
  3264. $state = '';
  3265. }
  3266. $label = config('toc.label');
  3267. if (empty($label)) {
  3268. $label = 'Table of Contents';
  3269. }
  3270. $style = config('toc.style');
  3271. if ($style == 'default' || empty($style)) {
  3272. $style = '<link rel="stylesheet" id="default-toc-style" href="'. site_url() .'system/resources/css/toc.css" type="text/css" media="all">';
  3273. } else {
  3274. $style = '';
  3275. }
  3276. $load = <<<EOF
  3277. <script>
  3278. document.addEventListener("DOMContentLoaded", function() {
  3279. if (document.getElementById('toc-wrapper.{$id}').parentNode.classList.contains('{$id}')) {
  3280. generateTOC('.{$id}');
  3281. } else {
  3282. document.getElementById('toc-wrapper.{$id}').parentNode.classList.add('{$id}');
  3283. generateTOC('.{$id}');
  3284. }
  3285. });
  3286. </script>
  3287. EOF;
  3288. $result = $part_1 . '<div class="toc-wrapper" id="toc-wrapper.'. $id .'" style="display:none;" >'. $load . $style .'<details '. $state .'><summary title="'. $label .'"><span class="details">'. $label .'</span></summary><div class="inner"><div class="toc" id="toc.'. $id .'"></div></div></details><script src="'. site_url().'system/resources/js/toc.generator.js"></script></div>' . $part_2;
  3289. return $result;
  3290. }
  3291. // Automatically add toc after x paragraph
  3292. function automatic_toc($content, $id)
  3293. {
  3294. $pos = config('toc.position');
  3295. $exp = explode('</p>', $content);
  3296. if (is_null($pos) || $pos > count($exp)){
  3297. return $content;
  3298. }
  3299. array_splice($exp, $pos, 0, insert_toc($id) . '<p>');
  3300. $content = implode('</p>', $exp);
  3301. return $content;
  3302. }
  3303. function generate_title($type = null, $object = null)
  3304. {
  3305. if ($type == 'is_front') {
  3306. $format = config('home.title.format');
  3307. if (empty($format)) {
  3308. $format = '%blog_title% - %blog_tagline%';
  3309. }
  3310. $var_map = array('%blog_title%' => blog_title(), '%blog_tagline%' => blog_tagline(), '%blog_description%' => blog_description());
  3311. $var = strtr($format, $var_map);
  3312. return strip_tags($var);
  3313. } elseif ($type == 'is_post') {
  3314. $format = config('post.title.format');
  3315. if (empty($format)) {
  3316. $format = '%post_title% - %blog_title%';
  3317. }
  3318. $var_map = array('%blog_title%' => blog_title(), '%blog_tagline%' => blog_tagline(), '%blog_description%' => blog_description(), '%post_title%' => $object->title, '%post_description%' => $object->description, '%post_category%' => $object->categoryTitle, '%post_tag%' => $object->tag, '%post_author%' => $object->authorName, '%post_type%' => ucfirst($object->type));
  3319. $var = strtr($format, $var_map);
  3320. return strip_tags($var);
  3321. } elseif ($type == 'is_page' || $type == 'is_subpage') {
  3322. $format = config('page.title.format');
  3323. if (empty($format)) {
  3324. $format = '%page_title% - %blog_title%';
  3325. }
  3326. $var_map = array('%blog_title%' => blog_title(), '%blog_tagline%' => blog_tagline(), '%blog_description%' => blog_description(), '%page_title%' => $object->title, '%page_description%' => $object->description);
  3327. $var = strtr($format, $var_map);
  3328. return strip_tags($var);
  3329. } elseif ($type == 'is_profile') {
  3330. $format = config('profile.title.format');
  3331. if (empty($format)) {
  3332. $format = '%author_name% - %blog_title%';
  3333. }
  3334. $var_map = array('%blog_title%' => blog_title(), '%blog_tagline%' => blog_tagline(), '%blog_description%' => blog_description(), '%author_name%' => $object->title, '%author_description%' => $object->description);
  3335. $var = strtr($format, $var_map);
  3336. return strip_tags($var);
  3337. } elseif ($type == 'is_category') {
  3338. $format = config('category.title.format');
  3339. if (empty($format)) {
  3340. $format = '%category_title% - %blog_title%';
  3341. }
  3342. $var_map = array('%blog_title%' => blog_title(), '%blog_tagline%' => blog_tagline(), '%blog_description%' => blog_description(), '%category_title%' => $object->title, '%category_description%' => $object->description);
  3343. $var = strtr($format, $var_map);
  3344. return strip_tags($var);
  3345. } elseif ($type == 'is_tag') {
  3346. $format = config('tag.title.format');
  3347. if (empty($format)) {
  3348. $format = '%tag_title% - %blog_title%';
  3349. }
  3350. $var_map = array('%blog_title%' => blog_title(), '%blog_tagline%' => blog_tagline(), '%blog_description%' => blog_description(), '%tag_title%' => $object->title, '%tag_description%' => $object->description);
  3351. $var = strtr($format, $var_map);
  3352. return strip_tags($var);
  3353. } elseif ($type == 'is_archive') {
  3354. $format = config('archive.title.format');
  3355. if (empty($format)) {
  3356. $format = '%archive_title% - %blog_title%';
  3357. }
  3358. $var_map = array('%blog_title%' => blog_title(), '%blog_tagline%' => blog_tagline(), '%blog_description%' => blog_description(), '%archive_title%' => $object->title, '%archive_description%' => $object->description);
  3359. $var = strtr($format, $var_map);
  3360. return strip_tags($var);
  3361. } elseif ($type == 'is_search') {
  3362. $format = config('search.title.format');
  3363. if (empty($format)) {
  3364. $format = '%search_title% - %blog_title%';
  3365. }
  3366. $var_map = array('%blog_title%' => blog_title(), '%blog_tagline%' => blog_tagline(), '%blog_description%' => blog_description(), '%search_title%' => $object->title, '%search_description%' => $object->description);
  3367. $var = strtr($format, $var_map);
  3368. return strip_tags($var);
  3369. } elseif ($type == 'is_type') {
  3370. $format = config('type.title.format');
  3371. if (empty($format)) {
  3372. $format = '%type_title% - %blog_title%';
  3373. }
  3374. $var_map = array('%blog_title%' => blog_title(), '%blog_tagline%' => blog_tagline(), '%blog_description%' => blog_description(), '%type_title%' => $object->title, '%type_description%' => $object->description);
  3375. $var = strtr($format, $var_map);
  3376. return strip_tags($var);
  3377. } elseif ($type == 'is_blog') {
  3378. $format = config('blog.title.format');
  3379. if (empty($format)) {
  3380. $format = 'Blog - %blog_title%';
  3381. }
  3382. $var_map = array('%blog_title%' => blog_title(), '%blog_tagline%' => blog_tagline(), '%blog_description%' => blog_description());
  3383. $var = strtr($format, $var_map);
  3384. return strip_tags($var);
  3385. } elseif ($type == 'is_default') {
  3386. $format = config('default.title.format');
  3387. if (empty($format)) {
  3388. $format = '%page_title% - %blog_title%';
  3389. }
  3390. $var_map = array('%blog_title%' => blog_title(), '%blog_tagline%' => blog_tagline(), '%blog_description%' => blog_description(), '%page_title%' => $object);
  3391. $var = strtr($format, $var_map);
  3392. return strip_tags($var);
  3393. }
  3394. }
  3395. function generate_meta($type = null, $object = null)
  3396. {
  3397. $tags = '';
  3398. $defaultImg = config('default.image');
  3399. if (empty($defaultImg)) {
  3400. $defaultImg = site_url() . 'system/resources/images/logo-big.png';
  3401. }
  3402. $fbApp = config('fb.appid');
  3403. $facebook = config('social.facebook');
  3404. $twitter = config('social.twitter');
  3405. if (is_null($object)) {
  3406. if ($type == 'is_blog') {
  3407. $tags .= '<title>'. generate_title('is_blog', null) .'</title>' . "\n";
  3408. $tags .= '<link rel="canonical" href="'. site_url() . blog_path() .'" />' . "\n";
  3409. $tags .= '<meta name="description" content="'. blog_title() . ' ' . blog_string() .'"/>' . "\n";
  3410. $tags .= '<meta property="og:title" content="'. safe_html(generate_title('is_blog', null)) . '" />' . "\n";
  3411. $tags .= '<meta property="og:description" content="'. blog_title() . ' ' . blog_string() .'" />' . "\n";
  3412. $tags .= '<meta property="og:url" content="'. site_url() . blog_path() .'" />' . "\n";
  3413. } else {
  3414. $tags .= '<title>'. generate_title('is_front', null) .'</title>' . "\n";
  3415. $tags .= '<link rel="canonical" href="'. site_url() .'" />' . "\n";
  3416. $tags .= '<meta name="description" content="'. safe_html(strip_tags(blog_description())) .'"/>' . "\n";
  3417. $tags .= '<meta property="og:title" content="'. safe_html(generate_title('is_front', null)) . '" />' . "\n";
  3418. $tags .= '<meta property="og:description" content="'. safe_html(strip_tags(blog_description())) .'" />' . "\n";
  3419. $tags .= '<meta property="og:url" content="'. site_url() .'" />' . "\n";
  3420. }
  3421. $tags .= '<meta property="og:locale" content="'. locale_language() .'" />' . "\n";
  3422. $tags .= '<meta property="og:type" content="website" />' . "\n";
  3423. $tags .= '<meta property="og:site_name" content="'. blog_title() . '" />' . "\n";
  3424. $tags .= '<meta property="og:image" content="'. $defaultImg .'" />' . "\n";
  3425. $tags .= '<meta name="twitter:card" content="summary_large_image" />' . "\n";
  3426. if(!empty($twitter)) {
  3427. $twitter = parse_url($twitter);
  3428. $tags .= '<meta name="twitter:site" content="'. str_replace('/', '@', $twitter['path']) .'" />' . "\n";
  3429. }
  3430. if (!empty($fbApp)) {
  3431. $tags .= '<meta property="fb:app_id" content="'. $fbApp .'" />' . "\n";
  3432. }
  3433. } else {
  3434. if(!empty($object->image)) {
  3435. $image = $object->image;
  3436. } else {
  3437. $image = get_image($object->body);
  3438. if(empty($image)) {
  3439. $image = $defaultImg;
  3440. }
  3441. }
  3442. if ($type == 'is_post') {
  3443. $tags .= '<title>'. generate_title('is_post',$object) .'</title>' . "\n";
  3444. $tags .= '<meta name="author" content="'. safe_html($object->authorName) .'" />' . "\n";
  3445. $tags .= '<meta name="article:published_time" content="'. date('c', $object->date) .'" />' . "\n";
  3446. $tags .= '<meta name="article:modified_time" content="'. date('c', $object->lastMod) .'" />' . "\n";
  3447. $tags .= '<meta name="article:section" content="'. safe_html($object->categoryTitle) .'" />' . "\n";
  3448. $tags .= '<meta name="article:section_url" content="'. $object->categoryUrl .'" />' . "\n";
  3449. } elseif ($type == 'is_page' || $type == 'is_subpage') {
  3450. $tags .= '<title>'. generate_title('is_page',$object) .'</title>' . "\n";
  3451. $tags .= '<meta name="article:modified_time" content="'. date('c', $object->lastMod) .'" />' . "\n";
  3452. } else {
  3453. $tags .= '<title>'. generate_title($type , $object) .'</title>' . "\n";
  3454. }
  3455. $tags .= '<link rel="canonical" href="'. $object->url .'" />' . "\n";
  3456. $tags .= '<meta name="description" content="'. safe_html($object->description) .'"/>' . "\n";
  3457. if(!empty($facebook)) {
  3458. $tags .= '<meta property="article:publisher" content="'. $facebook .'" />' . "\n";
  3459. }
  3460. if(!empty($twitter)) {
  3461. $twitter = parse_url($twitter);
  3462. $tags .= '<meta name="twitter:creator" content="'. str_replace('/', '@', $twitter['path']) .'" />' . "\n";
  3463. $tags .= '<meta name="twitter:site" content="'. str_replace('/', '@', $twitter['path']) .'" />' . "\n";
  3464. }
  3465. $tags .= '<meta property="og:locale" content="'. locale_language() .'" />' . "\n";
  3466. $tags .= '<meta property="og:site_name" content="'. blog_title() . '" />' . "\n";
  3467. $tags .= '<meta property="og:type" content="article" />' . "\n";
  3468. $tags .= '<meta property="og:title" content="'. safe_html($object->title) .'" />' . "\n";
  3469. $tags .= '<meta property="og:url" content="'. $object->url .'" />' . "\n";
  3470. $tags .= '<meta property="og:description" content="'. safe_html($object->description) .'" />' . "\n";
  3471. $tags .= '<meta name="twitter:card" content="summary_large_image" />' . "\n";
  3472. $tags .= '<meta property="og:image" content="'. $image .'" />' . "\n";
  3473. if (!empty($fbApp)) {
  3474. $tags .= '<meta property="fb:app_id" content="'. $fbApp .'" />' . "\n";
  3475. }
  3476. }
  3477. return $tags;
  3478. }