2

I have a php script getting all folders in a posts folder and making them into a list.

I have a $postinfo_str variable assigned to a json file for each folder which I am using to store post date and category/tag info etc in.

I also have a $pagetitle variable assigned to a title.php include file for each folder. So say I am on a "June 2018" archive page, the text in that file will be "June 2018". If I am on say a "Tutorials" category page, that will be the text in the title.php.

In the json file, I have:

{
     "Arraysortdate": "YYYYMMDD",
     "Month": "Month YYYY",
     "Category": ["cat1", "cat2", "etc"]
 }

I am ordering the array newest to oldest using krsort with Arraysortdate as key.

How do I filter the array using $pagetitle as input, finding if there is a match in $postinfo_str, and if there isn't, remove that folder from the array?

All I can seem to find regarding array sorting is where the info in the $pageinfo_str is basically the array and so by that, the $title is the input and the output is the matching text from the $postinfo_str, whereas I want the output to be the folders that only have the matching text in the $postinfo_str to what the input ($pagetitle) is.

Here is my code I have.. Keep in mind this is flat file, I do not want a database to achieve this. See comments if you want an explaination.

<?php 

 $BASE_PATH = '/path/to/public_html';
 
 // initial array containing the dirs
     $dirs = glob($BASE_PATH.'/testblog/*/posts/*', GLOB_ONLYDIR);

 // new array with date as key
     $dirinfo_arr = [];
     foreach ($dirs as $cdir) {

  // get current page title from file
      $pagetitle = file_get_contents("includes/title.php");
 
  // get date & post info from file
      $dirinfo_str = file_get_contents("$cdir/includes/post-info.json");
      $dirinfo = json_decode($dirinfo_str, TRUE);

  // add current directory to the info array
      $dirinfo['dir'] = $cdir;
  // add current dir to new array where date is the key
      $dirinfo_arr[$dirinfo['Arraysortdate']] = $dirinfo;
 }
 // now we sort the new array
     krsort($dirinfo_arr);

     foreach($dirinfo_arr as $key=>$dir) {
      $dirpath = $dir['dir'];
  $dirpath = str_replace('/path/to/public_html/', '', $dirpath);

?>


       <!--HTML HERE SUCH AS--!>
       
           <a href="<?=$dirpath;?>"> TEXT </a><br>

<?php
};
?>

Jase Wolf
  • 23
  • 7
  • For people wondering why I am choosing to create a flat file cms & database free blog where I have to do things manually. I have a lot of includes being used so I have my code in one place. Sure I still have to copy a folder each time to create a new post as well as create a new month/year folder each time it's a new month/year. And same for categories/tags if I create new ones. – Jase Wolf Jun 28 '18 at 09:08
  • But just copy another, edit the info a bit, job done. Sure the other two issues is that I have no automatic way of doing an RSS xml, and also that the more folders equal the more it takes to find something. But then even with trillions of things, just find the folder name for the post as in the url. And I don't post enough either way for an RSS to be much of an issue to do myself or for it to even really matter as I share what I post on social media, and for a viewer, it's no different than a static site when the content is already there. – Jase Wolf Jun 28 '18 at 09:09
  • For me, the benefits of no cms and flat file is I can use any text editor I like via ftp/ssh to just paste things I write instead of dealing with a cms, then once done, I can forget about it, in the same way with the rest of my site, without any worry I need to update the cms/plugins for security. And then the fact that my blog is just 100% tied into the rest of my site's html/css with no changing things about to work to how a certain cms wants it, which usually is also seperate with the fact my blogs aren't starting from in the root too. – Jase Wolf Jun 28 '18 at 09:09
  • So, please do not tell me to use a cms or a database. Sure to you it may sound the stupidest thing ever to not do something the usual way, or your way. But you have your reasons, I have mine. Thanks – Jase Wolf Jun 28 '18 at 09:09

1 Answers1

0

I have difficulties following your problem description. Your code example is slightly confusing. It appears to load the same global includes/title.php for each directory. Meaning, the value of $pagetitle should be the same every iteration. If this is intended, you should probably move that line right outside the loop. If the file contains actual php code, you should probably use

$pagetitle = include 'includes/title.php'; 

or something similar. If it doesn't, you should probably name it title.txt. If it is not one global file, you should probably add the path to the file_get_contents/include as well. (However, why wouldn't you just add the title in the json struct?)

I'm under the assumption that this happened by accident when trying to provide a minimal code example (?) ... In any case, my answer won't be the perfect answer, but it hopefully can be adapted once understood ;o)

If you only want elements in your array, that fulfill certain properties, you have essentially two choices:

  1. don't put those element in (mostly your code)

    foreach ($dirs as $cdir) {
    
        // get current page title from file
        $pagetitle = file_get_contents("includes/title.php");
    
        // get date & post info from file
        $dirinfo_str = file_get_contents("$cdir/includes/post-info.json");
        $dirinfo = json_decode($dirinfo_str, TRUE);
    
        // add current directory to the info array
        $dirinfo['dir'] = $cdir;
        // add current dir to new array where date is the key
    
     // ------------ NEW --------------
        $filtercat = 'cat1';
        if(!in_array($filtercat, $dirinfo['Category'])) {
             continue;
        }
     // -------------------------------
    
        $dirinfo_arr[$dirinfo['Arraysortdate']] = $dirinfo;
    
  2. array_filter the array afterwards, by providing a anonymous function

     // ----- before cycling through $dirinfo_arr for output
     $filtercat = 'cat1';
     $filterfunc = function($dirinfo) use ($filtercat) {
         return in_array($filtercat, $dirinfo['Category']));
     }
    
     $dirinfo_arr = array_filter($dirinfo_arr, $filterfunc);
    

    you should read up about anonymous functions and how you provide local vars to them, to ease the pain. maybe your use case is bettersuited for array_reduce, which is similar, except you can determine the output of your "filter".

$new = array_filter($array, $func), is just a fancy way of writing:

$new = [];
foreach($array as $key => $value) {
    if($func($value)) {
        $new[$key] = $value;
    }
}

update 1

in my code samples, you could replace in_array($filtercat, $dirinfo['Category']) with in_array($pagetitle, $dirinfo) - if you want to match on anything that's in the json-struct (base level) - or with ($pagetitle == $dirinfo['Month']) if you just want to match the month.

update 2

I understand, that you're probably just starting with php or even programming, so the concept of some "huge database" may be frightening. But tbh, the filesystem is - from a certain point of view - a database as well. However, it usually is quite slow in comparison, it also doesn't provide many features.

In the long run, I would strongly suggest using a database. If you don't like the idea of putting your data in "some database server", use sqlite. However, there is a learning curve involved, if you never had to deal with databases before. In the long run it will be time worth spending, because it simplifys so many things.

Jakumi
  • 7,105
  • 2
  • 11
  • 28
  • Hi, the reasoning for the title.php seemingly being the same, as that's the page title for the current page you currently are on. So for the page cat1/, where the title is "catagory 1", that will be the title the script finds. If it's the cat2 page, the script will see the title.php for cat2, as that's now the current directory the script is working from. Hopefully that explains to you better. I'll get back if I have any issue – Jase Wolf Jun 28 '18 at 07:43
  • Btw here's my thread on WebDeveloper regarding this coding, where it started from and why it's where it is now. Just in case that may help you work out better what I'm wanting. Though you seem tk have a clear idea of that so I appreciate it! https://www.webdeveloper.com/forum/d/381704-sort-a-php-array-order-using-contents-of-a-file-such-as-date-php – Jase Wolf Jun 28 '18 at 07:47
  • Also, regarding my use of title.php, I'm using it to include the text written in there on pages. If I can do something instead to just use a specific set of info from a json somewhere on a page, including some values being multi line, that'd be great and I will start using that instad of individual php files. As I just wasn't aware of json until I started this venture via my WebDeveloper thread. – Jase Wolf Jun 28 '18 at 08:00
  • You sir are an absolute LEGEND!! In your first example after the new comment, I removed the first $filtercat line and as per you saying, changed the if line to not include ['Catagory'], and changed $filtercat to $pagetitle. That works brilliantly for month pages, however for category pages, it won't do it until I add ['Categories'] back. Any ideas what I can change in my json to get categories to work wthout me having to specify ['Categories']? – Jase Wolf Jun 28 '18 at 09:00
  • well seperating each category as 1,, 2, 3, 4 etc on new lines, that does the trick. But if there's any way I can keep them on the same line like before, that'd be great! p.s: excuse the saying ['Categories"] not ['Category'] – Jase Wolf Jun 28 '18 at 09:20
  • @JaseWolf try this particular alternative to `in_array`: https://stackoverflow.com/a/4128377/4275413 – Jakumi Jun 28 '18 at 11:53
  • Currently just have them as seperate scripts right now so that works fine. Though if I can do `in_array_r` like the short method with if & continue that'd be great as that works flawlessly just changing `$filtercat` to `$pagetitle` and removing the `$filtercat = 'cat1';` line above. But using the second method, I'm keep breaking the page even just leaving the code as it is where it is looking for `cat1` in `['Category']`. – Jase Wolf Jun 29 '18 at 03:32
  • you can also use a combined approach like `if(!in_array($filtercat, $dirinfo) && !in_array($filtercat, $dirinfo['Category'])) { continue; }`. – Jakumi Jun 29 '18 at 06:53