Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I am wondering how might I create an admin page to do CRUD. I know how to add a basic/options page to the admin menu. But I want to go further, how might I manage data (CRUD) and for the index/listing page, I will need pagination, can someone point me in the right direction?

share|improve this question
add comment

2 Answers 2

I ended up with coding up some classes.

Credits: http://design.sparklette.net/teaches/how-to-add-wordpress-pagination-without-a-plugin/

On 2nd thought very long but works... if anyone improves it, it will be great to add a link in comments :)

class Pager {
    protected $table;
    protected $pages;
    protected $perpage;
    protected $page;
    protected $wpdb;
    protected $otherSQL;

    public function __construct($table, $perpage, $page, $otherSQL = '') {
        global $wpdb;
        $this->wpdb = $wpdb;
        $this->table = $wpdb->prefix . $table;
        $this->perpage = $perpage;
        $this->page = $page;
        $this->pages = ceil($wpdb->get_var('SELECT COUNT(*) FROM ' . $this->table) / $this->perpage);
        $this->otherSQL = $otherSQL;
    }

    protected function getFirstPageURL() {
        return UrlUtils::appendQueryString('pagenum', 1);
    }

    protected function getPrevPageURL() {
        return UrlUtils::appendQueryString('pagenum', $this->page == 1 ? 1 : $this->pagenum - 1);
    }

    protected function getNextPageURL() {
        return UrlUtils::appendQueryString('pagenum', $this->page == $this->pages ? $this->pages : $this->page + 1);
    }

    protected function getLastPageURL() {
        return UrlUtils::appendQueryString('pagenum', $this->pages);
    }

    protected function getPageURL($page) {
        return UrlUtils::appendQueryString('pagenum', $page);
    }

    public function generatePagination($range = 2) {
        $shown = $range * 2 + 1;
        ?>
        <div class="tablenav">
            <div class="tablenav-pages">
                <span class="displaying-num"><?php echo $this->pages; ?> page(s)</span>
                <a href="<?php echo $this->getFirstPageURL(); ?>" <?php if ($this->page == 1) echo 'class="disabled"';  ?>>&laquo;</a>
                <a href="<?php echo $this->getPrevPageURL(); ?>" <?php if ($this->page == 1) echo 'class="disabled"';  ?>>&lsaquo;</a> 

                <?php
                for ($i = 1; $i <= $this->pages; $i++) { 
                    if ($this->pages != 1 &&( !($i >= $this->pages + $shown || $i <= $this->page - $shown) || $this->pages <= $shown )) {
                        echo '<a href="' . $this->getPageURL($i) . '" ' . ($i == $this->page ? 'class="disabled"' : '' ) . '>' . $i . '</a>';
                    }
                }
                ?>

                <a href="<?php echo $this->getNextPageURL(); ?>" <?php if ($this->page == $this->pages) echo 'class="disabled"';  ?>>&raquo;</a>
                <a href="<?php echo $this->getLastPageURL(); ?>" <?php if ($this->page == $this->pages) echo 'class="disabled"';  ?>>&rsaquo;</a>
            </div>
        </div>
        <?php
    }

    public function getPageData() {
        $data = $this->wpdb->get_results('SELECT * FROM ' . $this->table . ' ' . $this->otherSQL . ' LIMIT ' . ($this->page - 1) * $this->perpage . ', ' . $this->perpage, OBJECT );
        return $data;
    }

}

class UrlUtils {

    public static function parseQueryString($url = '') {
        $queryArr = array();
        $queryStr = $_SERVER['QUERY_STRING'];
        if (!empty($url)) {
            $queryStr = parse_url($url, PHP_URL_QUERY);
        }
        parse_str($queryStr, $queryArr);
        return $queryArr;
    }

    public static function appendQueryString($key, $val, $url = "") {
        $queryArr = self::parseQueryString($url);
        $queryArr[$key] = $val;
        $queryStr = http_build_query($queryArr);

        $url = empty($url) ? $_SERVER['PHP_SELF'] : $url;
        $parts = parse_url($url);
        $parts['query'] = $queryStr;

        return $parts['path'] . '?' . $parts['query'];
    }

    public static function removeQueryString($remove) {
        $queryArr = self::parseQueryString();
        if (is_array($remove)) {
            foreach ($remove as  $r) {
                if (array_key_exists($r, $queryArr)) {
                    unset($queryArr[$r]);
                }
            }
        } else {
            if (array_key_exists($remove, $queryArr)) {
                unset($queryArr[$remove]);
            }
        }

        $queryStr = http_build_query($queryArr);
        return $_SERVER['PHP_SELF'] . '?' . $queryStr;
    }

}

// Usage like

require_once('inc/pager.php');
$pager = new Pager('km_contact', 20, (isset($_GET['pagenum']) && is_numeric($_GET['pagenum'])) ? $_GET['pagenum'] : 1, 'ORDER BY dt DESC');
$contacts = $pager->getPageData();

...

<?php foreach ($contacts as $c) : ?>
    <tr>
        <td><?php echo $c->name; ?></td>
        <td><a href="mailto:<?php echo $c->name; ?>"><?php echo $c->email; ?></a></td>
        <td><?php echo $c->subject; ?></td>
        <td><?php echo $c->content; ?></td>
        <td><a href="<?php echo UrlUtils::appendQueryString('viewid', $c->id); ?>">View</a></td>
    </tr>
<?php endforeach; ?>
...

$pager->generatePagination();
share|improve this answer
add comment

Hi @JM at Work:

The way to do CRUD in WordPress for probably 99% of use-cases is to create a Custom Post Type. CPTs will give you CRUD almost for free, then after that you may need to ask a few more questions here about how to do selected additional things, depending on your specific use-case. Good luck!

share|improve this answer
    
I know abt custom post type, but currently I have a plugin for newsletters so users can signup with their name+email which does not seem to fit well in a post (I will have a empty post and store name/email in custom fields?) –  JM at Work Apr 4 '11 at 9:42
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.