<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://en.doc.boardgamearena.com/index.php?action=history&amp;feed=atom&amp;title=ItemManager</id>
	<title>ItemManager - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://en.doc.boardgamearena.com/index.php?action=history&amp;feed=atom&amp;title=ItemManager"/>
	<link rel="alternate" type="text/html" href="http://en.doc.boardgamearena.com/index.php?title=ItemManager&amp;action=history"/>
	<updated>2026-10-20T11:25:26Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.0</generator>
	<entry>
		<id>http://en.doc.boardgamearena.com/index.php?title=ItemManager&amp;diff=31333&amp;oldid=prev</id>
		<title>Thoun: /* ItemManager overview */</title>
		<link rel="alternate" type="text/html" href="http://en.doc.boardgamearena.com/index.php?title=ItemManager&amp;diff=31333&amp;oldid=prev"/>
		<updated>2026-09-07T08:07:23Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;ItemManager overview&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 10:07, 7 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l19&quot;&gt;Line 19:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 19:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;*Three field kinds are mandatory: &amp;lt;code&amp;gt;ID&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;LOCATION&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;ORDER&amp;lt;/code&amp;gt;.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;*Three field kinds are mandatory: &amp;lt;code&amp;gt;ID&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;LOCATION&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;ORDER&amp;lt;/code&amp;gt;.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;ItemManager methods return instances of your item class rather than associative arrays. Methods returning several items use a &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;code&amp;gt;&lt;/del&gt;Collection&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/code&amp;gt; &lt;/del&gt;keyed by item ID.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;ItemManager methods return instances of your item class rather than associative arrays. Methods returning several items use a &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[&lt;/ins&gt;Collection&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;]] &lt;/ins&gt;keyed by item ID.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===A basic item class===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===A basic item class===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Thoun</name></author>
	</entry>
	<entry>
		<id>http://en.doc.boardgamearena.com/index.php?title=ItemManager&amp;diff=31331&amp;oldid=prev</id>
		<title>Thoun at 08:04, 7 September 2026</title>
		<link rel="alternate" type="text/html" href="http://en.doc.boardgamearena.com/index.php?title=ItemManager&amp;diff=31331&amp;oldid=prev"/>
		<updated>2026-09-07T08:04:14Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 10:04, 7 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l573&quot;&gt;Line 573:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 573:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[Category:Studio]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Thoun</name></author>
	</entry>
	<entry>
		<id>http://en.doc.boardgamearena.com/index.php?title=ItemManager&amp;diff=31293&amp;oldid=prev</id>
		<title>Thoun at 08:20, 4 September 2026</title>
		<link rel="alternate" type="text/html" href="http://en.doc.boardgamearena.com/index.php?title=ItemManager&amp;diff=31293&amp;oldid=prev"/>
		<updated>2026-09-04T08:20:42Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;//en.doc.boardgamearena.com/index.php?title=ItemManager&amp;amp;diff=31293&amp;amp;oldid=31292&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Thoun</name></author>
	</entry>
	<entry>
		<id>http://en.doc.boardgamearena.com/index.php?title=ItemManager&amp;diff=31292&amp;oldid=prev</id>
		<title>Thoun at 08:19, 4 September 2026</title>
		<link rel="alternate" type="text/html" href="http://en.doc.boardgamearena.com/index.php?title=ItemManager&amp;diff=31292&amp;oldid=prev"/>
		<updated>2026-09-04T08:19:10Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 10:19, 4 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l524&quot;&gt;Line 524:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 524:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Existing columns are skipped. This helper only adds columns; data migrations or other schema changes still require an explicit upgrade query.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Existing columns are skipped. This helper only adds columns; data migrations or other schema changes still require an explicit upgrade query.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;== Migrating from Deck ==&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;To match the old tables, you&#039;ll need to specify the dbField for all five columns pre-existing.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;pre&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;#[Item(&#039;card&#039;)]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;class Card&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    #[ItemField(kind: ItemFieldKind::ID, dbField: &#039;card_id&#039;)]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    public int $id;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    #[ItemField(kind: ItemFieldKind::LOCATION, locationIndex: 0, dbField: &#039;card_location&#039;)]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    public string $location;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    #[ItemField(kind: ItemFieldKind::LOCATION, locationIndex: 1, dbField: &#039;card_location_arg&#039;)]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    public ?int $location_arg;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    #[ItemField(kind: ItemFieldKind::ORDER)]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    public int $order;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    #[ItemField(dbField: &#039;card_type&#039;)]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    public int $type;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    #[ItemField(dbField: &#039;card_type_arg&#039;)]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    public int $type_arg;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/pre&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;In this example, I kept the same field names, so you&#039;ll access your values with &amp;lt;code&gt;$card-&gt;type&amp;lt;/code&gt; instead of &amp;lt;code&gt;$card[&#039;type&#039;]&amp;lt;/code&gt;. You can change the name to &amp;lt;code&gt;suit&amp;lt;/code&gt; or whatever you like!&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Note that the array object was returning string values even for numeric columns, while the Card object now returns proper typings. Make sure your code works with proper typing.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;As the ItemManager instanciate the table, remove from the dbmodel.sql file the table creation.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;You will also need to add the order field, as the card_location_arg was doing the order but also some other stuff, with something like this (adapt to your locations using order):&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;pre&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    function upgradeTableDb($from_version) {&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;        if ($from_version &amp;lt;= 2605041658) {&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;            $sql = &quot;ALTER TABLE `DBPREFIX_card` ADD `order` INT DEFAULT 0, MODIFY `card_location_arg` INT NULL&quot;;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;            $this-&gt;applyDbUpgradeToAllDB($sql);&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;            $sql = &quot;UPDATE `DBPREFIX_card` SET `order` = `card_location_arg` WHERE `card_location` = &#039;deck&#039;&quot;;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;            $this-&gt;applyDbUpgradeToAllDB($sql);&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;            $sql = &quot;UPDATE `DBPREFIX_card` SET `card_location_arg` = NULL WHERE `card_location` = &#039;deck&#039;&quot;;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;            $this-&gt;applyDbUpgradeToAllDB($sql);&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;        }&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    }&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/pre&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Thoun</name></author>
	</entry>
	<entry>
		<id>http://en.doc.boardgamearena.com/index.php?title=ItemManager&amp;diff=31266&amp;oldid=prev</id>
		<title>Thoun: /* Custom fields */</title>
		<link rel="alternate" type="text/html" href="http://en.doc.boardgamearena.com/index.php?title=ItemManager&amp;diff=31266&amp;oldid=prev"/>
		<updated>2026-09-02T12:03:33Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Custom fields&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 14:03, 2 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l85&quot;&gt;Line 85:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 85:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;#[ItemField(kind: ItemFieldKind::ID, dbField: &amp;#039;card_id&amp;#039;)]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;#[Item(&amp;#039;card&amp;#039;)]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;public int $id;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;class Card&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    &lt;/ins&gt;#[ItemField(kind: ItemFieldKind::ID, dbField: &amp;#039;card_id&amp;#039;)]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    &lt;/ins&gt;public int $id;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;#[ItemField(dbField: &amp;#039;card_type&amp;#039;)]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    #[ItemField(kind: ItemFieldKind::LOCATION, locationIndex: 0, dbField: &amp;#039;card_location&amp;#039;)]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;public int $type;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    public string $location;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    #[ItemField(kind: ItemFieldKind::LOCATION, locationIndex: 1, dbField: &amp;#039;card_location_arg&amp;#039;)]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    public ?int $location_arg;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    #[ItemField(kind: ItemFieldKind::ORDER)]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    public int $order;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    &lt;/ins&gt;#[ItemField(dbField: &amp;#039;card_type&amp;#039;)]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    &lt;/ins&gt;public int $type;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    #[ItemField(dbField: &amp;#039;card_type_arg&amp;#039;)]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    public int $type_arg;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/pre&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;In that case, you wil also need to add the order field on running tables, like this:&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;pre&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    function upgradeTableDb($from_version) {&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;        if ($from_version &amp;lt;= 2605041658) {&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;            $sql = &amp;quot;ALTER TABLE `DBPREFIX_card` ADD `order` INT DEFAULT 0&amp;quot;;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;            $this-&amp;gt;applyDbUpgradeToAllDB($sql);&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;        }&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    }&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Thoun</name></author>
	</entry>
	<entry>
		<id>http://en.doc.boardgamearena.com/index.php?title=ItemManager&amp;diff=31258&amp;oldid=prev</id>
		<title>Thoun: Created page with &quot;{{Studio_Framework_Navigation}}  &quot;ItemManager&quot; is a PHP component for storing and manipulating game objects. It is the object-oriented successor to the Deck component: instead of forcing every object into the five card fields, it maps a PHP class of your choice to a database table.  With ItemManager, you can: * Store cards, tiles, dice, tokens, or other game objects as typed PHP objects. * Add custom persisted fields directly to the object class. * Organize items in orde...&quot;</title>
		<link rel="alternate" type="text/html" href="http://en.doc.boardgamearena.com/index.php?title=ItemManager&amp;diff=31258&amp;oldid=prev"/>
		<updated>2026-09-02T09:00:08Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;{{Studio_Framework_Navigation}}  &amp;quot;ItemManager&amp;quot; is a PHP component for storing and manipulating game objects. It is the object-oriented successor to the Deck component: instead of forcing every object into the five card fields, it maps a PHP class of your choice to a database table.  With ItemManager, you can: * Store cards, tiles, dice, tokens, or other game objects as typed PHP objects. * Add custom persisted fields directly to the object class. * Organize items in orde...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ItemManager&amp;quot; is a PHP component for storing and manipulating game objects. It is the object-oriented successor to the Deck component: instead of forcing every object into the five card fields, it maps a PHP class of your choice to a database table.&lt;br /&gt;
&lt;br /&gt;
With ItemManager, you can:&lt;br /&gt;
* Store cards, tiles, dice, tokens, or other game objects as typed PHP objects.&lt;br /&gt;
* Add custom persisted fields directly to the object class.&lt;br /&gt;
* Organize items in ordered locations and sub-locations.&lt;br /&gt;
* Move, pick, shuffle, query, and update items without writing SQL.&lt;br /&gt;
* Automatically create the corresponding database table during game setup.&lt;br /&gt;
&lt;br /&gt;
== ItemManager overview ==&lt;br /&gt;
&lt;br /&gt;
Each ItemManager manages one PHP item class and one database table. The class and its persisted properties are described with PHP attributes:&lt;br /&gt;
* &amp;lt;code&amp;gt;#[Item]&amp;lt;/code&amp;gt; on the class sets the table name.&lt;br /&gt;
* &amp;lt;code&amp;gt;#[ItemField]&amp;lt;/code&amp;gt; on a public property makes that property persistent.&lt;br /&gt;
* Three field kinds are mandatory: &amp;lt;code&amp;gt;ID&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;LOCATION&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;ORDER&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
ItemManager methods return instances of your item class rather than associative arrays. Methods returning several items use a &amp;lt;code&amp;gt;Collection&amp;lt;/code&amp;gt; keyed by item ID.&lt;br /&gt;
&lt;br /&gt;
=== A basic item class ===&lt;br /&gt;
&lt;br /&gt;
The following class describes ordinary playing cards:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
namespace Bga\Games\YourGame\Cards;&lt;br /&gt;
&lt;br /&gt;
use Bga\GameFramework\Components\ItemManager\Item;&lt;br /&gt;
use Bga\GameFramework\Components\ItemManager\ItemField;&lt;br /&gt;
use Bga\GameFramework\Components\ItemManager\ItemFieldKind;&lt;br /&gt;
&lt;br /&gt;
#[Item(&amp;#039;card&amp;#039;)]&lt;br /&gt;
class Card&lt;br /&gt;
{&lt;br /&gt;
    #[ItemField(kind: ItemFieldKind::ID)]&lt;br /&gt;
    public int $id;&lt;br /&gt;
&lt;br /&gt;
    #[ItemField(kind: ItemFieldKind::LOCATION, locationIndex: 0)]&lt;br /&gt;
    public string $location;&lt;br /&gt;
&lt;br /&gt;
    #[ItemField(kind: ItemFieldKind::LOCATION, locationIndex: 1)]&lt;br /&gt;
    public int|string|null $locationArg;&lt;br /&gt;
&lt;br /&gt;
    #[ItemField(kind: ItemFieldKind::ORDER)]&lt;br /&gt;
    public int $order;&lt;br /&gt;
&lt;br /&gt;
    #[ItemField]&lt;br /&gt;
    public int $suit;&lt;br /&gt;
&lt;br /&gt;
    #[ItemField]&lt;br /&gt;
    public int $value;&lt;br /&gt;
&lt;br /&gt;
    // This property has no #[ItemField], so it is not stored in the database.&lt;br /&gt;
    public string $displayName;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The mandatory fields have the following roles:&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;ID&amp;#039;&amp;#039;&amp;#039;: the unique integer identifier. An integer ID is generated automatically when an item is created.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;LOCATION&amp;#039;&amp;#039;&amp;#039;: one or more values describing where the item is. Location indexes must start at 0 and be consecutive.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;ORDER&amp;#039;&amp;#039;&amp;#039;: the item&amp;#039;s zero-based position within its exact location. ItemManager keeps orders dense after moves.&lt;br /&gt;
&lt;br /&gt;
The field names are yours to choose. The &amp;lt;code&amp;gt;kind&amp;lt;/code&amp;gt; tells ItemManager which fields have the mandatory roles.&lt;br /&gt;
&lt;br /&gt;
The first location field must be a non-null &amp;lt;code&amp;gt;string&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;string|int&amp;lt;/code&amp;gt;. Additional location fields must have the same possible base types and be nullable, because some locations may not need every part. ID and ORDER fields must be non-null integers.&lt;br /&gt;
&lt;br /&gt;
=== Custom fields ===&lt;br /&gt;
&lt;br /&gt;
Any typed public property marked &amp;lt;code&amp;gt;#[ItemField]&amp;lt;/code&amp;gt; is stored. ItemManager infers its storage type from the PHP property type:&lt;br /&gt;
* &amp;lt;code&amp;gt;bool&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;string&amp;lt;/code&amp;gt; use scalar columns.&lt;br /&gt;
* Arrays, objects, interfaces, and enums use JSON.&lt;br /&gt;
* Nullable properties store &amp;lt;code&amp;gt;NULL&amp;lt;/code&amp;gt; when appropriate.&lt;br /&gt;
&lt;br /&gt;
Objects stored as JSON are reconstructed as their declared PHP class when read. Set &amp;lt;code&amp;gt;serialize: true&amp;lt;/code&amp;gt; only when PHP serialization is specifically required:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#[ItemField]&lt;br /&gt;
public ?CardToken $token = null;&lt;br /&gt;
&lt;br /&gt;
#[ItemField(serialize: true)]&lt;br /&gt;
public ?LegacyValue $legacyValue = null;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;dbField&amp;lt;/code&amp;gt; when the PHP property name differs from an existing database column. This is particularly useful when migrating a Deck table:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#[ItemField(kind: ItemFieldKind::ID, dbField: &amp;#039;card_id&amp;#039;)]&lt;br /&gt;
public int $id;&lt;br /&gt;
&lt;br /&gt;
#[ItemField(dbField: &amp;#039;card_type&amp;#039;)]&lt;br /&gt;
public int $type;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Locations and sub-locations ===&lt;br /&gt;
&lt;br /&gt;
Locations must be registered before they are used. A typical card manager declares these locations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Bga\GameFramework\Components\ItemManager\ItemLocation;&lt;br /&gt;
&lt;br /&gt;
$locations = [&lt;br /&gt;
    new ItemLocation(&amp;#039;deck&amp;#039;),&lt;br /&gt;
    new ItemLocation(&amp;#039;discard&amp;#039;),&lt;br /&gt;
    new ItemLocation(&amp;#039;table&amp;#039;),&lt;br /&gt;
    new ItemLocation(&amp;#039;hand&amp;#039;),&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For an item class with two LOCATION fields, &amp;lt;code&amp;gt;&amp;#039;deck&amp;#039;&amp;lt;/code&amp;gt; is a complete location whose second part is &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;, while &amp;lt;code&amp;gt;[&amp;#039;hand&amp;#039;, $playerId]&amp;lt;/code&amp;gt; identifies one player&amp;#039;s hand.&lt;br /&gt;
&lt;br /&gt;
Locations can be written in three equivalent forms where accepted:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;#039;deck&amp;#039;&lt;br /&gt;
[&amp;#039;hand&amp;#039;, $playerId]&lt;br /&gt;
Location::from(&amp;#039;hand&amp;#039;, $playerId)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For read methods, omitted trailing parts are unconstrained. A &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; in a non-trailing location part is also a wildcard, which lets a later part still be constrained. Arrays at a location part mean &amp;quot;any of these values&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Every player&amp;#039;s hand: locationIndex 1 is omitted.&lt;br /&gt;
$items-&amp;gt;getItemsInLocation(&amp;#039;hand&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
// Hands of players 12 and 34.&lt;br /&gt;
$items-&amp;gt;getItemsInLocation(Location::filter(&amp;#039;hand&amp;#039;, [12, 34]));&lt;br /&gt;
&lt;br /&gt;
// Items in either the deck or discard. The nested array filters locationIndex 0.&lt;br /&gt;
$items-&amp;gt;getItemsInLocation(Location::filter([[&amp;#039;deck&amp;#039;, &amp;#039;discard&amp;#039;]]));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Filters are read-only. Moving or picking always requires a concrete location.&lt;br /&gt;
&lt;br /&gt;
An ItemLocation name ending in &amp;lt;code&amp;gt;*&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;%&amp;lt;/code&amp;gt; registers a prefix wildcard. For example, &amp;lt;code&amp;gt;new ItemLocation(&amp;#039;played*&amp;#039;)&amp;lt;/code&amp;gt; accepts &amp;lt;code&amp;gt;&amp;#039;played1&amp;#039;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;#039;played2&amp;#039;&amp;lt;/code&amp;gt;, and so on. Prefer separate location fields when the suffix is structured data such as a player ID.&lt;br /&gt;
&lt;br /&gt;
=== Creating an ItemManager ===&lt;br /&gt;
&lt;br /&gt;
Create the manager in your game or in a dedicated domain manager. Using a dedicated manager keeps item rules, queries, and notifications together.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use Bga\GameFramework\Components\ItemManager\ItemLocation;&lt;br /&gt;
use Bga\GameFramework\Components\ItemManager\ItemManager;&lt;br /&gt;
use Bga\Games\YourGame\Game;&lt;br /&gt;
use Bga\Games\YourGame\Cards\Card;&lt;br /&gt;
&lt;br /&gt;
class CardManager&lt;br /&gt;
{&lt;br /&gt;
    private ItemManager $items;&lt;br /&gt;
&lt;br /&gt;
    public function __construct(Game $game)&lt;br /&gt;
    {&lt;br /&gt;
        $this-&amp;gt;items = $game-&amp;gt;bga-&amp;gt;itemManagerFactory-&amp;gt;createItemManager(&lt;br /&gt;
            Card::class,&lt;br /&gt;
            locations: ItemLocation::getDefaults(),&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function initDb() {&lt;br /&gt;
        $this-&amp;gt;items-&amp;gt;initDb();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function setup() {&lt;br /&gt;
        $cards = [];&lt;br /&gt;
        foreach ([1, 2, 3, 4] as $suit) {&lt;br /&gt;
            foreach (range(2, 14) as $value) {&lt;br /&gt;
                $cards[] = [&lt;br /&gt;
                    &amp;#039;location&amp;#039; =&amp;gt; &amp;#039;deck&amp;#039;,&lt;br /&gt;
                    &amp;#039;suit&amp;#039; =&amp;gt; $suit,&lt;br /&gt;
                    &amp;#039;value&amp;#039; =&amp;gt; $value,&lt;br /&gt;
                ];&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;items-&amp;gt;createItems($cards);&lt;br /&gt;
        $this-&amp;gt;items-&amp;gt;shuffle(&amp;#039;deck&amp;#039;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At the beginning of &amp;lt;code&amp;gt;setupNewGame&amp;lt;/code&amp;gt;, create the database table, then create the initial items:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;cardManager-&amp;gt;initDb();&lt;br /&gt;
$this-&amp;gt;cardManager-&amp;gt;setup();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not also declare the generated table in &amp;lt;code&amp;gt;dbmodel.sql&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;initDb()&amp;lt;/code&amp;gt; creates it from the item class.&lt;br /&gt;
&lt;br /&gt;
=== Simple examples ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Deal five cards to each player.&lt;br /&gt;
foreach (array_keys($players) as $playerId) {&lt;br /&gt;
    $this-&amp;gt;cards-&amp;gt;pickItems(5, &amp;#039;deck&amp;#039;, [&amp;#039;hand&amp;#039;, $playerId]);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return a typed Collection&amp;lt;Card&amp;gt;.&lt;br /&gt;
$hand = $this-&amp;gt;cards-&amp;gt;getItemsInLocation([&amp;#039;hand&amp;#039;, $playerId]);&lt;br /&gt;
&lt;br /&gt;
// Send a plain list to the client rather than an object keyed by card ID.&lt;br /&gt;
$result[&amp;#039;_private&amp;#039;][&amp;#039;hand&amp;#039;] = $hand-&amp;gt;values();&lt;br /&gt;
&lt;br /&gt;
// Change and persist one custom property.&lt;br /&gt;
$card-&amp;gt;faceUp = true;&lt;br /&gt;
$this-&amp;gt;cards-&amp;gt;updateItem($card, &amp;#039;faceUp&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
// Move a card object; passing its ID would also work.&lt;br /&gt;
$this-&amp;gt;cards-&amp;gt;moveItem($card, &amp;#039;discard&amp;#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ItemManager component reference ==&lt;br /&gt;
&lt;br /&gt;
=== Attributes and supporting types ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;#[Item( ?string $tableName = null )]&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Marks a class as managed by ItemManager. &amp;lt;code&amp;gt;$tableName&amp;lt;/code&amp;gt; is the database table name. If omitted, the short class name is used. A table name can belong to only one managed class during a request.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;#[ItemField( ?ItemFieldKind $kind = null, ?string $type = null, ?string $dbField = null, bool $serialize = false, int $locationIndex = 0 )]&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Marks a typed public property as persisted.&lt;br /&gt;
* &amp;lt;code&amp;gt;$kind&amp;lt;/code&amp;gt;: &amp;lt;code&amp;gt;ItemFieldKind::ID&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ItemFieldKind::LOCATION&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ItemFieldKind::ORDER&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; for a custom field.&lt;br /&gt;
* &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;: normally inferred. Supported values are &amp;lt;code&amp;gt;bool&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;double&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;string&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;json&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;$dbField&amp;lt;/code&amp;gt;: database column name; defaults to the PHP property name.&lt;br /&gt;
* &amp;lt;code&amp;gt;$serialize&amp;lt;/code&amp;gt;: stores an object using PHP serialization instead of JSON.&lt;br /&gt;
* &amp;lt;code&amp;gt;$locationIndex&amp;lt;/code&amp;gt;: the zero-based position of a LOCATION field.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;new ItemLocation( string|int $name, bool $randomPick = false, string|int|ItemLocation|null $autoReshuffleFrom = null, ?callable $autoReshuffleCallback = null )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Declares an accepted top-level location.&lt;br /&gt;
* &amp;lt;code&amp;gt;$randomPick&amp;lt;/code&amp;gt; shuffles that location before each pick, which is useful for a bag.&lt;br /&gt;
* &amp;lt;code&amp;gt;$autoReshuffleFrom&amp;lt;/code&amp;gt; names another registered location to move and shuffle into this one when a pick cannot find enough items.&lt;br /&gt;
* &amp;lt;code&amp;gt;$autoReshuffleCallback&amp;lt;/code&amp;gt; runs after an automatic reshuffle.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;ItemLocation::getDefaults( bool $reshuffleDiscardToDeck = true )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Returns declarations for &amp;lt;code&amp;gt;deck&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;discard&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;table&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;hand&amp;lt;/code&amp;gt;. By default, picking from an insufficient deck automatically moves the discard pile into the deck and shuffles it.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Location::from( array|string|int|Location $location, string|int|null ...$locations )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Creates a concrete location. Pass either one list, one existing Location, or separate location parts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Location::from(&amp;#039;deck&amp;#039;);&lt;br /&gt;
Location::from([&amp;#039;hand&amp;#039;, $playerId]);&lt;br /&gt;
Location::from(&amp;#039;hand&amp;#039;, $playerId);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Location::filter( array|string|int|Location $location, string|int|array|null ...$locations )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Creates a read-only location filter. A &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; part matches every value at that index, and an array part matches any value in that array. Use filters only with &amp;lt;code&amp;gt;getItemsInLocation&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;countItemsInLocation&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Initializing ItemManager ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;$this-&amp;gt;bga-&amp;gt;itemManagerFactory-&amp;gt;createItemManager( string $className, ?callable $classNameResolver = null, array $locations = [], ?callable $dbUpdateCallback = null, ?callable $countChangeCallback = null )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Creates an ItemManager for &amp;lt;code&amp;gt;$className&amp;lt;/code&amp;gt; and registers &amp;lt;code&amp;gt;$locations&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The optional &amp;lt;code&amp;gt;$classNameResolver&amp;lt;/code&amp;gt; receives a database row, or &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;, and returns the class to instantiate. A returned class must extend the managed base class. Returning &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; uses the base class. This lets different item types carry their behavior in subclasses:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;items = $this-&amp;gt;bga-&amp;gt;itemManagerFactory-&amp;gt;createItemManager(&lt;br /&gt;
    PowerCard::class,&lt;br /&gt;
    classNameResolver: fn(?array $row) =&amp;gt; match ((int)($row[&amp;#039;type&amp;#039;] ?? 0)) {&lt;br /&gt;
        1 =&amp;gt; ExtraTurnCard::class,&lt;br /&gt;
        2 =&amp;gt; DrawTwoCard::class,&lt;br /&gt;
        default =&amp;gt; null,&lt;br /&gt;
    },&lt;br /&gt;
    locations: ItemLocation::getDefaults(),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The optional callbacks have these signatures:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dbUpdateCallback: function(string $tableName, array $linesByItemId, string $operation): void&lt;br /&gt;
countChangeCallback: function(string $tableName, array $changesByLocation): void&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$operation&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;&amp;#039;INSERT&amp;#039;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;#039;UPDATE&amp;#039;&amp;lt;/code&amp;gt;. Each count change contains &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt;, an array of location parts, and &amp;lt;code&amp;gt;count&amp;lt;/code&amp;gt;, the new count. These callbacks are useful for mirroring server-side changes; ordinary games usually do not need them.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;new ItemManager( string $className, ?callable $classNameResolver = null, ?callable $dbUpdateCallback = null, ?callable $countChangeCallback = null )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Constructs a manager directly. Prefer &amp;lt;code&amp;gt;$this-&amp;gt;bga-&amp;gt;itemManagerFactory-&amp;gt;createItemManager()&amp;lt;/code&amp;gt;, which also registers the supplied locations.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;initDb()&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Creates the database table from the managed class. Call this at the beginning of &amp;lt;code&amp;gt;setupNewGame&amp;lt;/code&amp;gt;, before &amp;lt;code&amp;gt;createItems()&amp;lt;/code&amp;gt; or any query.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;addLocation( ItemLocation $location )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Registers one accepted location.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;addLocations( array $locations )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Registers several ItemLocation objects. Duplicate names and unknown &amp;lt;code&amp;gt;autoReshuffleFrom&amp;lt;/code&amp;gt; references cause a configuration exception.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;getLocationByName( string|int $locationName )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Returns the matching registered ItemLocation, including a prefix wildcard match, or &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; if no location matches.&lt;br /&gt;
&lt;br /&gt;
=== Creating items ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;createItems( array $itemsTypes )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Creates items from arrays whose keys are the PHP property names marked with &amp;lt;code&amp;gt;#[ItemField]&amp;lt;/code&amp;gt;. The special &amp;lt;code&amp;gt;item_nbr&amp;lt;/code&amp;gt; key creates multiple copies and defaults to 1. An integer ID is generated automatically, and ORDER is assigned at the end of each location unless explicitly supplied.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;items-&amp;gt;createItems([&lt;br /&gt;
    [&amp;#039;location&amp;#039; =&amp;gt; &amp;#039;deck&amp;#039;, &amp;#039;type&amp;#039; =&amp;gt; 1, &amp;#039;item_nbr&amp;#039; =&amp;gt; 4],&lt;br /&gt;
    [&amp;#039;location&amp;#039; =&amp;gt; &amp;#039;table&amp;#039;, &amp;#039;type&amp;#039; =&amp;gt; 2, &amp;#039;faceUp&amp;#039; =&amp;gt; true],&lt;br /&gt;
    [&lt;br /&gt;
        &amp;#039;location&amp;#039; =&amp;gt; &amp;#039;hand&amp;#039;,&lt;br /&gt;
        &amp;#039;locationArg&amp;#039; =&amp;gt; $playerId,&lt;br /&gt;
        &amp;#039;type&amp;#039; =&amp;gt; 3,&lt;br /&gt;
    ],&lt;br /&gt;
]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The location is mandatory. Unknown properties, invalid locations, and a negative &amp;lt;code&amp;gt;item_nbr&amp;lt;/code&amp;gt; cause a configuration exception. The input rows are randomized before insertion, so creation order must not be used to infer hidden item types. This method returns no IDs; query the items after creation if they are needed.&lt;br /&gt;
&lt;br /&gt;
=== Picking items ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;pickItem( Location|array|string|int $from, Location|array|string|int $to )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Picks the top item from one concrete location, moves it to the end (top) of another, and returns the updated item. Returns &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; when nothing can be picked.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;pickItems( int $number, Location|array|string|int $from, Location|array|string|int $to )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Picks up to &amp;lt;code&amp;gt;$number&amp;lt;/code&amp;gt; items from the top of &amp;lt;code&amp;gt;$from&amp;lt;/code&amp;gt;, moves them to &amp;lt;code&amp;gt;$to&amp;lt;/code&amp;gt;, and returns a Collection keyed by item ID. Fewer items can be returned when the source is exhausted.&lt;br /&gt;
&lt;br /&gt;
If the source has &amp;lt;code&amp;gt;randomPick: true&amp;lt;/code&amp;gt;, it is shuffled before selecting. If it has &amp;lt;code&amp;gt;autoReshuffleFrom&amp;lt;/code&amp;gt; and contains too few items, the remaining source items are picked first, the configured location is moved into the source and shuffled, and picking continues.&lt;br /&gt;
&lt;br /&gt;
=== Moving and ordering items ===&lt;br /&gt;
&lt;br /&gt;
Within a location, lower ORDER values are at the beginning and the highest ORDER is the top. Moves reindex affected locations to consecutive values starting at 0.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;moveAllItemsInLocation( Location|array|string|int|null $from, Location|array|string|int $to )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Moves every item from &amp;lt;code&amp;gt;$from&amp;lt;/code&amp;gt; to the end of &amp;lt;code&amp;gt;$to&amp;lt;/code&amp;gt;, preserving their relative order. Pass &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;$from&amp;lt;/code&amp;gt; to gather all managed items into the destination.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;setItemOrder( object|int $itemOrItemId, int $order )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Moves an item to the requested position within its current location. The position is clamped to the location bounds.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;moveItem( object|int $itemOrItemId, Location|array|string|int $to, ?int $order = null )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Moves one item, supplied as an object or ID. By default it is appended to the destination. Set &amp;lt;code&amp;gt;$order&amp;lt;/code&amp;gt; to insert it before the item currently at that position; use 0 to prepend it.&lt;br /&gt;
&lt;br /&gt;
When an item object is supplied, ItemManager also updates that object&amp;#039;s LOCATION and ORDER properties to their persisted values.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;moveItems( array|Collection $itemsOrItemIds, Location|array|string|int $to, bool $prepend = false )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Moves item objects, IDs, or a Collection as one ordered block. Their existing relative order is retained. The block is appended by default or inserted at the beginning when &amp;lt;code&amp;gt;$prepend&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;. Duplicate item IDs are moved only once.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;getMaxOrderInLocation( Location|array|string|int $location )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Returns the highest ORDER currently used by items matching the supplied concrete location parts. It returns 0 when no item matches. Supply every sub-location part when you want the maximum for only one sub-location.&lt;br /&gt;
&lt;br /&gt;
=== Getting items ===&lt;br /&gt;
&lt;br /&gt;
All methods returning several items return a &amp;lt;code&amp;gt;Collection&amp;lt;/code&amp;gt; of typed item objects keyed by item ID. Use &amp;lt;code&amp;gt;-&amp;gt;values()&amp;lt;/code&amp;gt; when a plain zero-based array is needed, especially before sending items to the client.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;getItemById( int $id )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Returns the item with this ID, or &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; if it does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;getItemsByIds( array $ids, ?string $sortByField = null, bool $reversed = false )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Returns items whose IDs are in &amp;lt;code&amp;gt;$ids&amp;lt;/code&amp;gt;. Set &amp;lt;code&amp;gt;$sortByField&amp;lt;/code&amp;gt; to a managed PHP property name. &amp;lt;code&amp;gt;$reversed&amp;lt;/code&amp;gt; sorts that field descending instead of ascending.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;getItemsByFieldName( string $fieldName, mixed $values, ?int $limit = null, ?string $sortByField = null, bool $reversed = false )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Returns items whose named managed property equals &amp;lt;code&amp;gt;$values&amp;lt;/code&amp;gt;. Pass an array to match any of several values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$blueItems = $this-&amp;gt;items-&amp;gt;getItemsByFieldName(&amp;#039;color&amp;#039;, &amp;#039;blue&amp;#039;);&lt;br /&gt;
$redOrBlue = $this-&amp;gt;items-&amp;gt;getItemsByFieldName(&amp;#039;color&amp;#039;, [&amp;#039;red&amp;#039;, &amp;#039;blue&amp;#039;]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An empty values array returns an empty Collection. &amp;lt;code&amp;gt;$limit&amp;lt;/code&amp;gt; restricts the result size. Sorting is applied only when &amp;lt;code&amp;gt;$sortByField&amp;lt;/code&amp;gt; is supplied.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;getItemsByFieldNames( array $filters, ?int $limit = null, ?string $sortByField = null, bool $reversed = false )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Combines several named field filters with AND. Each value can be one value or an array of accepted values. Both associative and tuple forms are accepted:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$cards = $this-&amp;gt;items-&amp;gt;getItemsByFieldNames([&lt;br /&gt;
    &amp;#039;type&amp;#039; =&amp;gt; [3, 4],&lt;br /&gt;
    &amp;#039;location&amp;#039; =&amp;gt; &amp;#039;hand&amp;#039;,&lt;br /&gt;
    &amp;#039;locationArg&amp;#039; =&amp;gt; $playerId,&lt;br /&gt;
]);&lt;br /&gt;
&lt;br /&gt;
$sameCards = $this-&amp;gt;items-&amp;gt;getItemsByFieldNames([&lt;br /&gt;
    [&amp;#039;type&amp;#039;, [3, 4]],&lt;br /&gt;
    [&amp;#039;location&amp;#039;, &amp;#039;hand&amp;#039;],&lt;br /&gt;
    [&amp;#039;locationArg&amp;#039;, $playerId],&lt;br /&gt;
]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An empty filter list returns all items, subject to the optional limit and sorting.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;getItemsByField( ItemField $field, mixed $values, ?int $limit = null, ?string $sortByField = null, bool $reversed = false )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The ItemField-object variant of &amp;lt;code&amp;gt;getItemsByFieldName()&amp;lt;/code&amp;gt;. In ordinary game code, prefer the field-name method.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;getItemsByFields( array $filters, ?int $limit = null, ?string $sortByField = null, bool $reversed = false )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The ItemField-object variant of &amp;lt;code&amp;gt;getItemsByFieldNames()&amp;lt;/code&amp;gt;. Each entry is &amp;lt;code&amp;gt;[$field, $values]&amp;lt;/code&amp;gt;, and filters are combined with AND. In ordinary game code, prefer the field-name method.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;countItemsInLocation( Location|array|string|int $location )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Returns the number of items matching a location or location filter. Non-trailing &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; parts and arrays of accepted values can be used as described under Locations and sub-locations.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;getItemsInLocation( Location|array|string|int $location, bool $reversed = false, ?int $limit = null, ?string $sortByField = null )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Returns items matching a location or location filter. By default, items are sorted by ORDER ascending. Set &amp;lt;code&amp;gt;$reversed&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; for descending order, &amp;lt;code&amp;gt;$limit&amp;lt;/code&amp;gt; to restrict the result size, or &amp;lt;code&amp;gt;$sortByField&amp;lt;/code&amp;gt; to sort by another managed property.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Bottom to top.&lt;br /&gt;
$hand = $this-&amp;gt;items-&amp;gt;getItemsInLocation([&amp;#039;hand&amp;#039;, $playerId]);&lt;br /&gt;
&lt;br /&gt;
// The three highest-valued items in the discard pile.&lt;br /&gt;
$items = $this-&amp;gt;items-&amp;gt;getItemsInLocation(&lt;br /&gt;
    &amp;#039;discard&amp;#039;,&lt;br /&gt;
    reversed: true,&lt;br /&gt;
    limit: 3,&lt;br /&gt;
    sortByField: &amp;#039;value&amp;#039;,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;getAllItems( ?int $limit = null )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Returns all managed items, optionally limited. No ordering is guaranteed.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;getItemOnTop( Location|array|string|int $location )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Returns the matching item with the highest ORDER, or &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; when no item matches. Supply every sub-location part when you want the top of only one sub-location.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;getItemsOnTop( int $number, Location|array|string|int $location )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Returns up to &amp;lt;code&amp;gt;$number&amp;lt;/code&amp;gt; matching items, ordered from top downward. Supply every sub-location part when you want items from only one sub-location.&lt;br /&gt;
&lt;br /&gt;
=== Updating items ===&lt;br /&gt;
&lt;br /&gt;
Changing a PHP object does not by itself change the database. Persist it with &amp;lt;code&amp;gt;updateItem()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;updateItems()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;updateItem( object $item, array|string|null $fields = null )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Persists properties from one managed item. Pass one property name or an array of names to update only those fields. Pass &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; to update every persisted property except ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$card-&amp;gt;faceUp = true;&lt;br /&gt;
$this-&amp;gt;items-&amp;gt;updateItem($card, &amp;#039;faceUp&amp;#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;updateItems( array|Collection $items, array|string|null $fields = null )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Persists several managed item objects. The &amp;lt;code&amp;gt;$fields&amp;lt;/code&amp;gt; argument behaves as in &amp;lt;code&amp;gt;updateItem()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;updateAllItems( string $fieldName, mixed $value )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Sets one named managed property to the same value for every item in the table. The ID field cannot be updated this way.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;getItemFromDb( ?array $dbItem )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Converts a raw database row into a typed managed item. Returns &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; for &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; or an empty row. The optional class-name resolver supplied when creating the manager selects the concrete class.&lt;br /&gt;
&lt;br /&gt;
=== Shuffling and hiding identifiers ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;shuffle( Location|array|string|int $location )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Randomizes the ORDER of all items matching the supplied concrete location parts. It does not change their IDs or location fields. Supply every sub-location part when each sub-location must be shuffled independently.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;changeIds( array|Collection $itemsOrItemIds )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changes the IDs of the supplied items and returns an array mapping each old ID to its new ID. Pass item objects, IDs, or a Collection. Supplied objects have their ID property updated.&lt;br /&gt;
&lt;br /&gt;
This is useful when previously visible items become hidden again, so players cannot track them by ID.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;changeIdsForLocation( Location|array|string|int $location )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changes the IDs of every item matching the supplied concrete location parts. This method returns no old-to-new mapping.&lt;br /&gt;
&lt;br /&gt;
=== Database upgrades ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;upgradeTableDbAddColumns( array $fieldNames )&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Adds columns for properties newly marked with &amp;lt;code&amp;gt;#[ItemField]&amp;lt;/code&amp;gt; after games already exist. Call it from &amp;lt;code&amp;gt;upgradeTableDb()&amp;lt;/code&amp;gt; with the PHP property names:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public function upgradeTableDb($fromVersion)&lt;br /&gt;
{&lt;br /&gt;
    if ($fromVersion &amp;lt;= 2609011200) {&lt;br /&gt;
        $this-&amp;gt;cards-&amp;gt;upgradeTableDbAddColumns([&amp;#039;target&amp;#039;, &amp;#039;faceUp&amp;#039;]);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Existing columns are skipped. This helper only adds columns; data migrations or other schema changes still require an explicit upgrade query.&lt;/div&gt;</summary>
		<author><name>Thoun</name></author>
	</entry>
</feed>