summaryrefslogtreecommitdiffstats
path: root/lib/Db/NewsMapper.php
blob: 14913c1beb61ec105e94a14e3b8346190b1b07aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<?php
/**
 * Nextcloud - News
 *
 * This file is licensed under the Affero General Public License version 3 or
 * later. See the COPYING file.
 *
 * @author    Alessandro Cosentino <cosenal@gmail.com>
 * @author    Bernhard Posselt <dev@bernhard-posselt.com>
 * @copyright 2012 Alessandro Cosentino
 * @copyright 2012-2014 Bernhard Posselt
 */

namespace OCA\News\Db;

use OCA\News\Utility\Time;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
use OCP\AppFramework\Db\QBMapper;
use OCP\IDBConnection;
use OCP\AppFramework\Db\Mapper;
use OCP\AppFramework\Db\Entity;

/**
 * Class NewsMapper
 *
 * @package OCA\News\Db
 */
abstract class NewsMapper extends Mapper
{
    const TABLE_NAME = '';

    /**
     * @var Time
     */
    private $time;

    /**
     * NewsMapper constructor.
     *
     * @param IDBConnection $db     Database connection
     * @param Time          $time   Time class
     * @param string        $entity Entity class
     */
    public function __construct(
        IDBConnection $db,
        Time $time,
        string $entity
    ) {
        parent::__construct($db, static::TABLE_NAME, $entity);
        $this->time = $time;
    }

    public function update(Entity $entity): Entity
    {
        $entity->setLastModified($this->time->getMicroTime());
        return parent::update($entity);
    }

    public function insert(Entity $entity): Entity
    {
        $entity->setLastModified($this->time->getMicroTime());
        return parent::insert($entity);
    }

    /**
     * Remove deleted items.
     *
     * @return void
     */
    public function purgeDeleted(): void
    {
        $builder = $this->db->getQueryBuilder();
        $builder->delete($this->tableName)
            ->where('deleted_at != 0')
            ->execute()
            ->execute();
    }

    abstract public function find(string $userId, int $id);

    /**
     * Find all items.
     *
     * @return Entity[]
     */
    abstract public function findAll(): array;

    /**
     * Find all items for a user.
     *
     * @param string $userId ID of the user
     *
     * @return Entity[]
     */
    abstract public function findAllFromUser(string $userId): array;

    /**
     * Find item for a user.
     *
     * @param string $userId ID of the user
     * @param int    $id     ID of the item
     *
     * @return Feed
     *
     * @throws DoesNotExistException            The item is not found
     * @throws MultipleObjectsReturnedException Multiple items found
     */
    abstract public function findFromUser(string $userId, int $id): Entity;



    /**
     * Performs a SELECT query with all arguments appened to the WHERE clause
     * The SELECT will be performed on the current table and take the entity
     * that is related for transforming the properties into column names
     *
     * Important: This method does not filter marked as deleted rows!
     *
     * @param array $search an assoc array from property to filter value
     * @param int|null $limit  Output limit
     * @param int|null $offset Output offset
     *
     * @depreacted Legacy function
     *
     * @return array
     */
    public function where(array $search = [], ?int $limit = null, ?int $offset = null)
    {
        $entity = new $this->entityClass();

        // turn keys into sql query filter, e.g. feedId -> feed_id = :feedId
        $filter = array_map(
            function ($property) use ($entity) {
                // check if the property actually exists on the entity to prevent
                // accidental Sql injection
                if (!property_exists($entity, $property)) {
                    $msg = 'Property ' . $property . ' does not exist on '
                        . $this->entityClass;
                    throw new \BadFunctionCallException($msg);
                }

                $column = $entity->propertyToColumn($property);
                return $column . ' = :' . $property;
            },
            array_keys($search)
        );

        $andStatement = implode(' AND ', $filter);

        $sql = 'SELECT * FROM `' . $this->getTableName() . '`';

        if (count($search) > 0) {
            $sql .= 'WHERE ' . $andStatement;
        }

        return $this->findEntities($sql, $search, $limit, $offset);
    }
}