Question

Let's suppose I have a database table called local_ads.

Now, when a local ad is created, one has to be able to view its preview and if he is satisfied, then save it. Also, if one wants to update a local ad, then he might want to see its preview before he overwrites the live version of the record.

So, I have a foreign key for the local_ads table called parent_id. If this is null, then it is a preview (at least according to my initial thoughts). Otherwise it is live. When one saves a preview, there are two cases:

Case 1: There was no live record yet linked to the preview. In this case a new record is inserted into the local_ads table with the parent_id pointing to the preview.

Case 2: There is a live record linked to the preview. In this case the live record is updated.

Everything looks and works nicely, but I have a problem showing the results in a grid. I want to show the preview if no live version of the record exists and only the live version if it exists. I would like to show something in the spirit of

select col1, col2, col3, col4
from local_ads glob
where (not (parent_id is null)) 
or ((select id from local_ads temp where temp.parent_id = glob.id limit 0, 1) is null)

but I have several problems. We have a logical or (I wonder how can I use logical or between logical operands using the build method of fRecordSet of flourishlib). Also, this query is of two dimensions, it is slow. Also, I wonder how can a sub-query be executed. Also, I do not know how can I use the is operator as in is null.

So, I had to re-think my idea and I came up with the following:

select col1, col2, col3, col4
from local_ads
where parent_id < id or parent_id >= id

the idea is simple: If a preview does not have a live version, then parent_id matches the id, otherwise the parent_id of a preview is null. I know this is an ugly hack, but this was the best idea I could came up with to solve the problem and decrease memory and performance complexity.

So, the only problem which remained was to check the two logical values in the where clause separated by the logical or.

From the documentation I have seen this:

 * 'column<:'                   => 'other_column'               // column < other_column

and this:

 * 'column>=:'                  => 'other_column'               // column >= other_column

so I know how can I add these to the filters, but how am I supposed to 'or' them?

So far I have tried it this way:

public static function localAd() {
    $User = Globe::load('CurrentUser');

    $Smarty = Globe::load('Smarty');

    //handle default options
    $options = array(
        'recordsPerPage' => 20,
        'pageLinks' => 10,
    );

    $page = 0;

    if (isset($_GET['p'])) {
        $page = $_GET['p'];
    }

    //get the data
    $startIndex = (isset($page)) ? $page * $options['recordsPerPage'] : 0;

    $filters = array();

    if ($User->getType() == 'local_admin') {
        $filters['domain='] = $User->getDomain();
    }

    $records = fRecordSet::build('LocalAd', $filters, array('created' => 'desc'), $options['recordsPerPage'], $page + 1);

    //create result object for pagination
    $Result = array(
        "recordsReturned" => $records->count(),
        "totalRecords" => $records->count(true),
        "startIndex" => intval($startIndex),
        "records" => $records->export(),
        'recordsPerPage' => $options['recordsPerPage'],
        'pageLinks' => $options['pageLinks'],
        'currentPage' => $page,
            //'options' => $options
    );

    $Result['totalPages'] = ceil($Result['totalRecords'] / $Result['recordsPerPage']);

    $Smarty->assign('Result', $Result);
    $Smarty->assign('ManagerURL', '?a=localAd');

    AdminView::display('Admin/LocalAd/main.tpl');
}

Note, that in some cases I have to check the domain as well.

Was it helpful?

Solution

In the meantime I have managed to solve the problem. This is how we can define the filter set to solve the problem mentioned in the question:

$filters = array();

if ($User->getType() == 'local_admin') {
  $filters['domain='] = $User->getDomain();
}

$filters['parent_id<:|parent_id>=:'] = array('id', 'id');
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top