Johan Broddfelt
/* Comments on code */
Donate $

Generating code

In the last post we created a list that will adapt and show data from any table. But there is one problem. I have a large text filed in my blog table. And it fills up the entire list. That is something one would read or edit after opening the page, not show in lists. We could of course automatically remove columns with large chunks of text and we actually might do that in another post. But right now I want to modify the code for my very specific need.

One way to do that is to just create a new file and add the necessary code. But that is to much coding for my taste. Instead I want to add a feature that will generate a complete file with code in the appropriate location, so that I only have to do a few modifications in order to get the list that I want.

Let's start by creating a copy of our list.php name list_code.php in the views/generic/ folder. Then we modify the index.php, with a $generate variable, like this:

        if (!is_file('views/' . $module . '/' . $view . '.php')) {
            $generate = filter_input(INPUT_GET, 'generate', FILTER_SANITIZE_URL);
            if ($generate != '') {
                $generate = '_'.$generate;
            }
            if (is_file('views/generic/' . $view . $generate . '.php')) {
                include('views/generic/' . $view . $generate . '.php');
            } else {
                echo '<div class="warning">The file ' . $view . '.php' . ' is missing!</div>';
            }
        } else {
            include('views/' . $module . '/' . $view . '.php');
        }

This means that if the file already is generated it will not be overwritten, unless deleted manually first. All we have to do is add the text &generate=code to the url.

Now let's modify our list_code.php so that it turns code into a string. Make sure you add all the columns separately into the string. Then we can create a file with the code and also print the code on the screen by replacing < with &lt;.

<?php
$fields = $obj->fetchFields();
$colCount = count($fields);
$code =
'<?php
    $searchText = filter_input(INPUT_GET, 'search_text', FILTER_SANITIZE_URL);
    $srchQry = '';
    if ($searchText != '') {
';
        $first = true;
        foreach ($fields as $field) {
            if (!$first) {
                $srchQry .= ' OR ';
            }
            $first = false;
            // Use UPPER to ignore case sensitive searches
            $srchQry .= 'UPPER(`' . $field->columnName . '`) LIKE UPPER('%' . $searchText . '%')';
        }
$code .= '      $srchQry = '' . $srchQry . '';
    } else {
        $srchQry = '1';
    }
    
    if (filter_input(INPUT_GET, 'orderby', FILTER_SANITIZE_URL) == '') {
        $orderBy = 'id';
    } else {
        $orderBy = filter_input(INPUT_GET, 'orderby', FILTER_SANITIZE_URL);
    }
    $desc = '';
    if (filter_input(INPUT_GET, 'desc', FILTER_SANITIZE_URL) == 1) {
        $desc = 'DESC';
    }
    $order = 'orderby=' . $orderBy . '&desc=' . filter_input(INPUT_GET, 'desc', FILTER_SANITIZE_URL);
    $orderBy = ' ORDER BY ' . $orderBy . ' ' . $desc;

    $postsPerPage = 20; // How many posts do you want to show per page
    $currentPage = (int)filter_input(INPUT_GET, 'current_page', FILTER_SANITIZE_NUMBER_INT);
    if ($currentPage == 0) { $currentPage = 1; } // We are on page 1 as default when current_page is not set.
    $index = ($currentPage * $postsPerPage) - $postsPerPage;
    $limit = '';
    if ($page != 0) {
        $limit = " LIMIT $index, $postsPerPage";
    }
    $total = $obj->fetchCount(' WHERE ' . $srchQry);
    $list = $obj->fetchArray(' WHERE ' . $srchQry . ' ' . $orderBy . ' ' . $limit);
    $pages = ceil((($total-1)/$postsPerPage));
    
    $query  = '&search_text=' . $searchText
            ;

    $pData  = '&module=' . $module
            . '&view=' . $view
            . '&id=' . $id
            ;

    $params = $pData
            . $query 
            ;
?>
<div>
    <h1>' . $obj->realClassName() . ' list</h1>
    <a href="?module='. $module . '&view=edit" class="button">New post</a>
    <form method="GET" action="">
        <input type="hidden" name="current_page" value="1">
        <input type="hidden" name="module" value="<?php echo $module; ?>">
        <input type="hidden" name="view" value="<?php echo $view; ?>">
        <input type="text" name="search_text" value="<?php echo $searchText; ?>">
        <input type="submit" class="button" name="search" value="Search">
    </form>
    <?php echo $total; ?> post<?php if ($total > 1) { echo 's'; } ?> found<br>
    <table class="list">
        <tr>
            <th width="40">Edit</th>
            <th width="60">Delete</th>
';
            foreach ($fields as $t) {
$code .= '                <th>
';
                if (preg_match("/_id$/", $t->columnName, $matches)) {
                    $columnArr = explode('-', $t->columnName);
$code .= '                    ' . Db::realClassName(str_replace('_id', '', $columnArr[0])) . '
';
                } else {
$code .= '                    ' . Db::realClassName($t->columnName) . '
';
                }
$code .= '                    <a href="?page=<?php echo $page; ?><?php echo $params; ?>&orderby=<?php echo $t->columnName; ?>&desc=1">-</a>
                    <a href="?page=<?php echo $page; ?><?php echo $params; ?>&orderby=<?php echo $t->columnName; ?>">+</a>
                </th>
';
            }
$code .= '        </tr>
        <?php foreach ($list as $item) { ?>
            <tr>
                <td>
                    <a href="?module=' . $module . '&view=edit&id=<?php echo $item->id; ?>">
                        Edit
                    </a>
                </td>
                <td>
                    <a href="?module=' . $module . '&view=list&id=<?php echo $item->id; ?>&cmd=del">
                        Delete
                    </a>
                </td>
';
                $cnt = 0;
                foreach ($fields as $t) {
                    $name = $t->varName;
$code .= '                <td>
';
                    if (preg_match("/_id$/", $t->columnName, $matches)) {
                        $columnArr = explode('-', $t->columnName);
                        if (count($columnArr) < 2) {
                          $columnArr[1] = $t->columnName;
                        }
                        $table = preg_replace("/_id$/", '', $columnArr[1]);
                        $className = preg_replace('/s/', '', ''.$obj->className($table));
                        $sc = new $className((int)$item->$name);
$code .= '                          <span class="noedit"><?php echo $sc->table_data[1]; ?></span>';
                    } else {
                        if ($cnt < 2) {
$code .= '                      <a href="?module=' . $module . '&view=edit&id=<?php echo $item->id; ?>">
';
                        }
$code .= '                          <?php echo $item->' . $name . '; ?>
';
                        if ($cnt < 2) { $code .= '                      </a>'; }
                        $cnt++;
                    }
$code .= '
';
$code .= '                </td>
';
                }
$code .= '            </tr>
';
$code .= '        <?php } ?>
        <tr><td colspan="' . ($colCount + 2) . '"><?php echo Html::paging($page, $pages, '&module=' . $module . '&id=' . $obj->id . '&view=' . $view . '&' . 

$query . '&' . $order); ?></td></tr>
    </table>
</div>
';
// Make dir if it does not exist. Named after $module
if (!is_dir('views/' . $module)) {
    mkdir('views/' . $module);
}
$fh = fopen('views/' . $module . '/' . $view . '.php', 'w');
fwrite($fh, $code);
fclose($fh);
?>
<div>
  <h1>File generated</h1>
  <pre><code><?php echo str_replace('<', '&lt;', $code); ?>
  </code></pre>
</div>

When the file has been generated you will no longer end up at the code generating view, but instead at the new file. And we can go in and manually edit that file to our liking.

As you might have noticed I use <pre><code> tags before I echo the code to the screen. This is because I use the highlightjs library for highlighting code. If you do not use that then just using <pre> is enough.

- Framework, PHP, Generic

<< One list to rule them all Edit on the fly >>

Comment

Name
Mail (Not public)
Send mail uppdates on new comments

Comments

0 post found