miniflux-legacy/models/group.php
Mathias Kresin c35dd27f01 remove all group from feeds before deleting
Main purpose is to prevent orphaned groups.

It's not possible to use the ON DELETE CASCADE trigger here, to remove
the group together with the last feed that is assigned to this group.

The ON DELETE CASCADE trigger will raise an foreign key violation error
in cases where the removed feed is not the last feed associated to a
group.

The purge_groups() call has been moved to the remove group functions,
since it's the only way to create an orphaned group.
2015-12-13 16:14:55 +01:00

246 lines
5.2 KiB
PHP

<?php
namespace Model\Group;
use PicoDb\Database;
/**
* Get all groups
*
* @return array
*/
function get_all()
{
return Database::getInstance('db')
->table('groups')
->orderBy('title')
->findAll();
}
/**
* Get assoc array of group ids with assigned feeds ids
*
* @return array
*/
function get_map()
{
$result = Database::getInstance('db')
->table('feeds_groups')
->findAll();
// TODO: add PDO::FETCH_COLUMN|PDO::FETCH_GROUP to picodb and use it instead
// of the following lines
$map = array();
foreach ($result as $row) {
$group_id = $row['group_id'];
$feed_id = $row['feed_id'];
if (isset($map[$group_id])) {
$map[$group_id][] = $feed_id;
}
else {
$map[$group_id] = array($feed_id);
}
}
return $map;
}
/**
* Get all groups assigned to feed
*
* @param integer $feed_id id of the feed
* @return array
*/
function get_feed_group_ids($feed_id)
{
return Database::getInstance('db')
->table('groups')
->join('feeds_groups', 'group_id', 'id')
->eq('feed_id', $feed_id)
->findAllByColumn('id');
}
/**
* Get the id of a group
*
* @param string $title group name
* @return mixed group id or false if not found
*/
function get_group_id($title)
{
return Database::getInstance('db')
->table('groups')
->eq('title', $title)
->findOneColumn('id');
}
/**
* Get all feed ids assigned to a group
*
* @param integer $group_id
* @return array
*/
function get_feeds_by_group($group_id)
{
return Database::getInstance('db')
->table('feeds_groups')
->eq('group_id', $group_id)
->findAllByColumn('feed_id');
}
/**
* Add a group to the Database
*
* Returns either the id of the new group or the id of an existing group with
* the same name
*
* @param string $title group name
* @return mixed id of the created group or false on error
*/
function create($title)
{
$data = array('title' => $title);
// check if the group already exists
$group_id = get_group_id($title);
// create group if missing
if ($group_id === false) {
Database::getInstance('db')
->table('groups')
->insert($data);
$group_id = get_group_id($title);
}
return $group_id;
}
/**
* Add groups to feed
*
* @param integer $feed_id feed id
* @param array $group_ids array of group ids
* @return boolean true on success, false on error
*/
function add($feed_id, $group_ids)
{
foreach ($group_ids as $group_id){
$data = array('feed_id' => $feed_id, 'group_id' => $group_id);
$result = Database::getInstance('db')
->table('feeds_groups')
->insert($data);
if ($result === false) {
return false;
}
}
return true;
}
/**
* Remove groups from feed
*
* @param integer $feed_id id of the feed
* @param array $group_ids array of group ids
* @return boolean true on success, false on error
*/
function remove($feed_id, $group_ids)
{
$result = Database::getInstance('db')
->table('feeds_groups')
->eq('feed_id', $feed_id)
->in('group_id', $group_ids)
->remove();
// remove empty groups
if ($result) {
purge_groups();
}
return $result;
}
/**
* Remove all groups from feed
*
* @param integer $feed_id id of the feed
* @return boolean true on success, false on error
*/
function remove_all($feed_id)
{
$result = Database::getInstance('db')
->table('feeds_groups')
->eq('feed_id', $feed_id)
->remove();
// remove empty groups
if ($result) {
purge_groups();
}
return $result;
}
/**
* Purge orphaned groups from database
*/
function purge_groups()
{
$groups = Database::getInstance('db')
->table('groups')
->join('feeds_groups', 'group_id', 'id')
->isnull('feed_id')
->findAllByColumn('id');
if (! empty($groups)) {
Database::getInstance('db')
->table('groups')
->in('id', $groups)
->remove();
}
}
/**
* Update feed group associations
*
* @param integer $feed_id id of the feed to update
* @param array $group_ids valid groups ids for feed
* @param string $create_group group to create and assign to feed
* @return boolean
*/
function update_feed_groups($feed_id, $group_ids, $create_group = '')
{
if ($create_group !== '') {
$id = create($create_group);
if ($id === false) {
return false;
}
if (! in_array($id, $group_ids)) {
$group_ids[] = $id;
}
}
$assigned = get_feed_group_ids($feed_id);
$superfluous = array_diff($assigned, $group_ids);
$missing = array_diff($group_ids, $assigned);
// remove no longer assigned groups from feed
if (! empty($superfluous) && ! remove($feed_id, $superfluous)) {
return false;
}
// add requested groups to feed
if (! empty($missing) && ! add($feed_id, $missing)) {
return false;
}
return true;
}