<?xml version="1.0" encoding="UTF-8"?>
<ae:configurations xmlns:ae="https://agavi.org/agavi/config/global/envelope/1.0"
xmlns="https://agavi.org/agavi/config/parts/database/1.0">
<ae:configuration>
<databases>
<database name="default" dsn="mysql:host=localhost;dbname=wasp;charset=utf8mb4"
user="wasp_user" password="secret"
persistent="false" />
</databases>
</ae:configuration>
</ae:configurations>
<?php
// app/lib/DoctrineHelper.php
class DoctrineHelper
{
private static $em = null;
public static function getEntityManager(): \Doctrine\ORM\EntityManager
{
if (self::$em === null) {
$config = new \Doctrine\ORM\Configuration();
$config->setProxyDir(sys_get_temp_dir() . '/doctrine_proxies');
$config->setAutoGenerateProxyClasses(true);
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache());
$config->setQueryCacheImpl(new \Doctrine\Common\Cache\ArrayCache());
$config->setResultCacheImpl(new \Doctrine\Common\Cache\ArrayCache());
// 讀取 Agavi 資料庫配置
$dbConfig = AgaviConfig::get('databases.default');
$conn = [
'driver' => 'pdo_mysql',
'host' => $dbConfig['host'] ?? 'localhost',
'dbname' => $dbConfig['dbname'] ?? 'wasp',
'user' => $dbConfig['user'] ?? 'root',
'password' => $dbConfig['password'] ?? '',
'charset' => 'utf8mb4',
];
self::$em = \Doctrine\ORM\EntityManager::create($conn, $config);
}
return self::$em;
}
}
./bin/agavi module-create
# Module name: Listing
./bin/agavi action-wizard
# Module: Listing
# Action: Display
# Views: Error Success
<?php
// app/lib/Entity/Listing.php
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="listing")
*/
class Listing
{
/** @ORM\Id @ORM\Column(type="integer") @ORM\GeneratedValue */
private $recordId;
/** @ORM\Column(type="string", length=100) */
private $ownerName;
/** @ORM\Column(type="string", length=50) */
private $vehicleModel;
/** @ORM\Column(type="integer") */
private $vehicleYear;
/** @ORM\Column(type="decimal", precision=10, scale=2) */
private $vehicleSalePriceMin;
// ... 其他欄位、getter/setter 省略
}
<?php
// app/modules/Listing/actions/DisplayAction.class.php
class Listing_DisplayAction extends AgaviAction
{
public function execute(AgaviRequestDataHolder $rd)
{
$id = $rd->getParameter('id');
if (!$id) {
return 'Error';
}
$em = DoctrineHelper::getEntityManager();
$listing = $em->find('Listing', (int)$id);
if (!$listing) {
return 'Error';
}
$this->setAttribute('listing', $listing);
return 'Success';
}
}
<?php // app/modules/Listing/templates/DisplaySuccess.php ?>
<h1><?= $listing->getVehicleModel() ?> (<?= $listing->getVehicleYear() ?>)</h1>
<dl class="dl-horizontal">
<dt>車主</dt><dd><?= $listing->getOwnerName() ?></dd>
<dt>價格區間</dt><dd><?= number_format($listing->getVehicleSalePriceMin()) ?> - <?= number_format($listing->getVehicleSalePriceMax()) ?></dd>
<dt>里程</dt><dd><?= number_format($listing->getVehicleMileage()) ?> km</dd>
<dt>顏色</dt><dd><?= $listing->getVehicleColor() ?></dd>
<dt>備註</dt><dd><?= nl2br($listing->getNote()) ?></dd>
</dl>
<p><a href="<?= $ro->gen('listing.index') ?>">回列表</a></p>
<route name="listing" pattern="^/listing" module="Listing">
<route name=".display" pattern="^/display/(?P\d+)$" action="Display" />
</route>
巢狀路由:`listing.display` 完整模式 `^/listing/display/(?P
INSERT INTO listing (RecordID, RecordDate, OwnerName, OwnerTel, OwnerEmail,
VehicleManufacturerID, VehicleModel, VehicleYear, VehicleColor, VehicleMileage,
VehicleIsFirstOwned, VehicleAccessoryBit, VehicleIsCertified, VehicleCertificationDate,
VehicleSalePriceMin, VehicleSalePriceMax, VehicleSalePriceIsNegotiable, Note,
OwnerCity, OwnerCountryID, DisplayStatus, DisplayUntilDate)
VALUES (1, '2024-01-15', 'John Doe', '0912345678', 'john@example.com',
2, 'Boxster', 2005, 'Yellow', 15457, 1, 23, 1,
'2023-01-01', 35000, 40000, 1, 'Well maintained.', 'Taipei', 1, 1, '2024-12-31');