+ /**
+ * @brief Insert a new item delivery data entry
+ *
+ * @param array $item The item fields that are to be inserted
+ */
+ private static function insertDeliveryData($delivery_data)
+ {
+ if (empty($delivery_data['iid']) || (empty($delivery_data['postopts']) && empty($delivery_data['inform']))) {
+ return;
+ }
+
+ DBA::insert('item-delivery-data', $delivery_data);
+ }
+
+ /**
+ * @brief Update an existing item delivery data entry
+ *
+ * @param integer $id The item id that is to be updated
+ * @param array $item The item fields that are to be inserted
+ */
+ private static function updateDeliveryData($id, $delivery_data)
+ {
+ if (empty($id) || (empty($delivery_data['postopts']) && empty($delivery_data['inform']))) {
+ return;
+ }
+
+ DBA::update('item-delivery-data', $delivery_data, ['iid' => $id], true);
+ }
+
+ /**
+ * @brief Insert a new item content entry
+ *
+ * @param array $item The item fields that are to be inserted
+ */
+ private static function insertActivity(&$item)
+ {
+ $activity_index = self::activityToIndex($item['verb']);
+
+ if ($activity_index < 0) {
+ return false;
+ }
+
+ $fields = ['uri' => $item['uri'], 'activity' => $activity_index,
+ 'uri-hash' => $item['uri-hash']];
+
+ // We just remove everything that is content
+ foreach (array_merge(self::CONTENT_FIELDLIST, self::MIXED_CONTENT_FIELDLIST) as $field) {
+ unset($item[$field]);
+ }
+
+ // To avoid timing problems, we are using locks.
+ $locked = Lock::acquire('item_insert_activity');
+ if (!$locked) {
+ logger("Couldn't acquire lock for URI " . $item['uri'] . " - proceeding anyway.");
+ }
+
+ // Do we already have this content?
+ $item_activity = DBA::selectFirst('item-activity', ['id'], ['uri-hash' => $item['uri-hash']]);
+ if (DBM::is_result($item_activity)) {
+ $item['iaid'] = $item_activity['id'];
+ logger('Fetched activity for URI ' . $item['uri'] . ' (' . $item['iaid'] . ')');
+ } elseif (DBA::insert('item-activity', $fields)) {
+ $item['iaid'] = DBA::lastInsertId();
+ logger('Inserted activity for URI ' . $item['uri'] . ' (' . $item['iaid'] . ')');
+ } else {
+ // This shouldn't happen.
+ logger('Could not insert activity for URI ' . $item['uri'] . ' - should not happen');
+ return false;
+ }
+ if ($locked) {
+ Lock::release('item_insert_activity');
+ }
+ return true;
+ }
+
+ /**
+ * @brief Insert a new item content entry
+ *
+ * @param array $item The item fields that are to be inserted
+ */
+ private static function insertContent(&$item)
+ {
+ $fields = ['uri' => $item['uri'], 'uri-plink-hash' => $item['uri-hash']];
+
+ foreach (array_merge(self::CONTENT_FIELDLIST, self::MIXED_CONTENT_FIELDLIST) as $field) {
+ if (isset($item[$field])) {
+ $fields[$field] = $item[$field];
+ unset($item[$field]);
+ }
+ }
+
+ // To avoid timing problems, we are using locks.
+ $locked = Lock::acquire('item_insert_content');
+ if (!$locked) {
+ logger("Couldn't acquire lock for URI " . $item['uri'] . " - proceeding anyway.");
+ }
+
+ // Do we already have this content?
+ $item_content = DBA::selectFirst('item-content', ['id'], ['uri-plink-hash' => $item['uri-hash']]);
+ if (DBM::is_result($item_content)) {
+ $item['icid'] = $item_content['id'];
+ logger('Fetched content for URI ' . $item['uri'] . ' (' . $item['icid'] . ')');
+ } elseif (DBA::insert('item-content', $fields)) {
+ $item['icid'] = DBA::lastInsertId();
+ logger('Inserted content for URI ' . $item['uri'] . ' (' . $item['icid'] . ')');
+ } else {
+ // This shouldn't happen.
+ logger('Could not insert content for URI ' . $item['uri'] . ' - should not happen');
+ }
+ if ($locked) {
+ Lock::release('item_insert_content');
+ }
+ }
+
+ /**
+ * @brief Update existing item content entries
+ *
+ * @param array $item The item fields that are to be changed
+ * @param array $condition The condition for finding the item content entries
+ */
+ private static function updateActivity($item, $condition)
+ {
+ if (empty($item['verb'])) {
+ return false;
+ }
+ $activity_index = self::activityToIndex($item['verb']);
+
+ if ($activity_index < 0) {
+ return false;
+ }
+
+ $fields = ['activity' => $activity_index];
+
+ logger('Update activity for ' . json_encode($condition));
+
+ DBA::update('item-activity', $fields, $condition, true);
+
+ return true;
+ }
+
+ /**
+ * @brief Update existing item content entries
+ *
+ * @param array $item The item fields that are to be changed
+ * @param array $condition The condition for finding the item content entries
+ */
+ private static function updateContent($item, $condition)
+ {
+ // We have to select only the fields from the "item-content" table
+ $fields = [];
+ foreach (array_merge(self::CONTENT_FIELDLIST, self::MIXED_CONTENT_FIELDLIST) as $field) {
+ if (isset($item[$field])) {
+ $fields[$field] = $item[$field];
+ }
+ }
+
+ if (empty($fields)) {
+ // when there are no fields at all, just use the condition
+ // This is to ensure that we always store content.
+ $fields = $condition;
+ }
+
+ logger('Update content for ' . json_encode($condition));
+
+ DBA::update('item-content', $fields, $condition, true);
+ }
+