+ /**
+ * @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'], 'plink' => $item['plink'],
+ 'uri-plink-hash' => hash('sha1', $item['plink']).hash('sha1', $item['uri'])];
+
+ foreach (self::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::set('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' => $item['uri']]);
+ 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 {
+ // By setting the ICID value through the worker we should avoid timing problems.
+ // When the locking works, this shouldn't be needed. But better be prepared.
+ Worker::add(PRIORITY_HIGH, 'SetItemContentID', $uri);
+ }
+ if ($locked) {
+ Lock::remove('item_insert_content');
+ }
+ }
+
+ /**
+ * @brief Set the item content id for a given URI
+ *
+ * @param string $uri The item URI
+ */
+ public static function setICIDforURI($uri)
+ {
+ $item_content = dba::selectFirst('item-content', ['id'], ['uri' => $uri]);
+ if (DBM::is_result($item_content)) {
+ dba::update('item', ['icid' => $item_content['id']], ['icid' => 0, 'uri' => $uri]);
+ logger('Asynchronously fetched content id for URI ' . $uri . ' (' . $item_content['id'] . ')');
+ } else {
+ logger('No item-content found for URI ' . $uri);
+ }
+ }
+
+ /**
+ * @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 (self::CONTENT_FIELDLIST as $field) {
+ if (isset($item[$field])) {
+ $fields[$field] = $item[$field];
+ }
+ }
+
+ if (empty($fields)) {
+ return;
+ }
+
+ if (!empty($item['plink'])) {
+ $fields['uri-plink-hash'] = hash('sha1', $item['plink']) . hash('sha1', $condition['uri']);
+ } else {
+ // Ensure that we don't delete the plink
+ unset($fields['plink']);
+ }
+
+ logger('Update content for URI ' . $condition['uri']);
+
+ dba::update('item-content', $fields, $condition, true);
+ }
+