Select the types of activity you want to include in your feed.
@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
···856856 'image/vnd.microsoft.icon' => true,
857857 ),
858858859859- // Phabricator can proxy images from other servers so you can paste the URI
860860- // to a funny picture of a cat into the comment box and have it show up as an
861861- // image. However, this means the webserver Phabricator is running on will
862862- // make HTTP requests to arbitrary URIs. If the server has access to internal
863863- // resources, this could be a security risk. You should only enable it if you
864864- // are installed entirely a VPN and VPN access is required to access
865865- // Phabricator, or if the webserver has no special access to anything. If
866866- // unsure, it is safer to leave this disabled.
867867- 'files.enable-proxy' => false,
868868-869869-870859// -- Storage --------------------------------------------------------------- //
871860872861 // Phabricator allows users to upload files, and can keep them in various
···307307308308= Embedding Media =
309309310310-If you set configuration flags, you can embed media directly in text:
310310+If you set a configuration flag, you can embed media directly in text:
311311312312- - **files.enable-proxy**: allows you to paste in image URLs and have them
313313- render inline.
314312 - **remarkup.enable-embedded-youtube**: allows you to paste in YouTube videos
315313 and have them render inline.
316314317317-These options are disabled by default because they have security and/or
318318-silliness implications, read their descriptions in ##default.conf.php## before
319319-enabling them.
315315+This option is disabled by default because it has security and/or
316316+silliness implications. Read the description in ##default.conf.php## before
317317+enabling it.
320318321319= Image Macros =
322320
···177177 const SERIALIZATION_PHP = 'php';
178178179179 const IDS_AUTOINCREMENT = 'ids-auto';
180180+ const IDS_COUNTER = 'ids-counter';
180181 const IDS_PHID = 'ids-phid';
181182 const IDS_MANUAL = 'ids-manual';
183183+184184+ const COUNTER_TABLE_NAME = 'lisk_counter';
182185183186 private $__dirtyFields = array();
184187 private $__missingFields = array();
···327330 * Lisk objects need to have a unique identifying ID. The three mechanisms
328331 * available for generating this ID are IDS_AUTOINCREMENT (default, assumes
329332 * the ID column is an autoincrement primary key), IDS_PHID (to generate a
330330- * unique PHID for each object) or IDS_MANUAL (you are taking full
331331- * responsibility for ID management).
333333+ * unique PHID for each object), IDS_MANUAL (you are taking full
334334+ * responsibility for ID management), or IDS_COUNTER (see below).
335335+ *
336336+ * InnoDB does not persist the value of `auto_increment` across restarts,
337337+ * and instead initializes it to `MAX(id) + 1` during startup. This means it
338338+ * may reissue the same autoincrement ID more than once, if the row is deleted
339339+ * and then the database is restarted. To avoid this, you can set an object to
340340+ * use a counter table with IDS_COUNTER. This will generally behave like
341341+ * IDS_AUTOINCREMENT, except that the counter value will persist across
342342+ * restarts and inserts will be slightly slower. If a database stores any
343343+ * DAOs which use this mechanism, you must create a table there with this
344344+ * schema:
345345+ *
346346+ * CREATE TABLE lisk_counter (
347347+ * counterName VARCHAR(64) COLLATE utf8_bin PRIMARY KEY,
348348+ * counterValue BIGINT UNSIGNED NOT NULL
349349+ * ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
332350 *
333351 * CONFIG_TIMESTAMPS
334352 * Lisk can automatically handle keeping track of a `dateCreated' and
···364382 * by Lisk (use readField and writeField instead), and you should not
365383 * directly access or assign protected members of your class (use the getters
366384 * and setters).
367367- *
368385 *
369386 * @return dictionary Map of configuration options to values.
370387 *
···11811198 return $this;
11821199 }
1183120011841184-11851201 /**
11861202 * Internal implementation of INSERT and REPLACE.
11871203 *
···11931209 $this->willSaveObject();
11941210 $data = $this->getPropertyValues();
1195121112121212+ $conn = $this->establishConnection('w');
12131213+11961214 $id_mechanism = $this->getConfigOption(self::CONFIG_IDS);
11971215 switch ($id_mechanism) {
11981216 case self::IDS_AUTOINCREMENT:
···12041222 unset($data[$id_key]);
12051223 }
12061224 break;
12251225+ case self::IDS_COUNTER:
12261226+ // If we are using counter IDs, assign a new ID if we don't already have
12271227+ // one.
12281228+ $id_key = $this->getIDKeyForUse();
12291229+ if (empty($data[$id_key])) {
12301230+ $counter_name = $this->getTableName();
12311231+ $id = self::loadNextCounterID($conn, $counter_name);
12321232+ $this->setID($id);
12331233+ $data[$id_key] = $id;
12341234+ }
12351235+ break;
12071236 case self::IDS_PHID:
12081237 if (empty($data[$this->getIDKeyForUse()])) {
12091238 $phid = $this->generatePHID();
···12181247 }
1219124812201249 $this->willWriteData($data);
12211221-12221222- $conn = $this->establishConnection('w');
1223125012241251 $columns = array_keys($data);
12251252···17591786 public function __set($name, $value) {
17601787 phlog('Wrote to undeclared property '.get_class($this).'::$'.$name.'.');
17611788 $this->$name = $value;
17891789+ }
17901790+17911791+ /**
17921792+ * Increments a named counter and returns the next value.
17931793+ *
17941794+ * @param AphrontDatabaseConnection Database where the counter resides.
17951795+ * @param string Counter name to create or increment.
17961796+ * @return int Next counter value.
17971797+ *
17981798+ * @task util
17991799+ */
18001800+ public static function loadNextCounterID(
18011801+ AphrontDatabaseConnection $conn_w,
18021802+ $counter_name) {
18031803+18041804+ // NOTE: If an insert does not touch an autoincrement row or call
18051805+ // LAST_INSERT_ID(), MySQL normally does not change the value of
18061806+ // LAST_INSERT_ID(). This can cause a counter's value to leak to a
18071807+ // new counter if the second counter is created after the first one is
18081808+ // updated. To avoid this, we insert LAST_INSERT_ID(1), to ensure the
18091809+ // LAST_INSERT_ID() is always updated and always set correctly after the
18101810+ // query completes.
18111811+18121812+ queryfx(
18131813+ $conn_w,
18141814+ 'INSERT INTO %T (counterName, counterValue) VALUES
18151815+ (%s, LAST_INSERT_ID(1))
18161816+ ON DUPLICATE KEY UPDATE
18171817+ counterValue = LAST_INSERT_ID(counterValue + 1)',
18181818+ self::COUNTER_TABLE_NAME,
18191819+ $counter_name);
18201820+18211821+ return $conn_w->getInsertID();
17621822 }
1763182317641824}
···9595 $this->assertEqual(true, (bool)$load->load((string)$id));
9696 }
97979898+ public function testCounters() {
9999+ $obj = new HarbormasterObject();
100100+ $conn_w = $obj->establishConnection('w');
101101+102102+ // Test that the counter bascially behaves as expected.
103103+ $this->assertEqual(1, LiskDAO::loadNextCounterID($conn_w, 'a'));
104104+ $this->assertEqual(2, LiskDAO::loadNextCounterID($conn_w, 'a'));
105105+ $this->assertEqual(3, LiskDAO::loadNextCounterID($conn_w, 'a'));
106106+107107+ // This first insert is primarily a test that the previous LAST_INSERT_ID()
108108+ // value does not bleed into the creation of a new counter.
109109+ $this->assertEqual(1, LiskDAO::loadNextCounterID($conn_w, 'b'));
110110+ $this->assertEqual(2, LiskDAO::loadNextCounterID($conn_w, 'b'));
111111+112112+ // These inserts alternate database connections. Since unit tests are
113113+ // transactional by default, we need to break out of them or we'll deadlock
114114+ // since the transactions don't normally close until we exit the test.
115115+ LiskDAO::endIsolateAllLiskEffectsToTransactions();
116116+ try {
117117+118118+ $conn_1 = $obj->establishConnection('w', $force_new = true);
119119+ $conn_2 = $obj->establishConnection('w', $force_new = true);
120120+121121+ $this->assertEqual(1, LiskDAO::loadNextCounterID($conn_1, 'z'));
122122+ $this->assertEqual(2, LiskDAO::loadNextCounterID($conn_2, 'z'));
123123+ $this->assertEqual(3, LiskDAO::loadNextCounterID($conn_1, 'z'));
124124+ $this->assertEqual(4, LiskDAO::loadNextCounterID($conn_2, 'z'));
125125+ $this->assertEqual(5, LiskDAO::loadNextCounterID($conn_1, 'z'));
126126+127127+ LiskDAO::beginIsolateAllLiskEffectsToTransactions();
128128+ } catch (Exception $ex) {
129129+ LiskDAO::beginIsolateAllLiskEffectsToTransactions();
130130+ throw $ex;
131131+ }
132132+ }
9813399134}