1: <?php
2:
3: namespace Himedia\Padocc\Properties;
4:
5: use GAubry\Shell\ShellAdapter;
6:
7: /**
8: * Gestionnaire de propriétés (table de hashage).
9: *
10: * Le nom des propriétés est insensible à la casse.
11: * Sait charger les fichiers de configuration PHP au format INI.
12: * Sait également charger les fichiers de configuration shell (qui acceptent la factorisation) au format suivant :
13: * PROPRIETE_1="chaîne"
14: * PROPRIETE_2="chaîne $PROPRIETE_1 chaîne"
15: *
16: * @author Geoffroy AUBRY <gaubry@hi-media.com>
17: */
18: class Adapter implements PropertiesInterface
19: {
20:
21: /**
22: * Table de hashage des propriétés (clé => valeur).
23: * @var array
24: */
25: private $aProperties;
26:
27: /**
28: * Shell adapter.
29: *
30: * @var ShellAdapter
31: * @see loadConfigShellFile()
32: */
33: private $oShell;
34:
35: /**
36: * Application config.
37: *
38: * @var array
39: */
40: private $aConfig;
41:
42: /**
43: * Constructeur.
44: *
45: * @param ShellAdapter $oShell instance utilisée pour charger les fichiers de configuration shell
46: * @param array $aConfig
47: */
48: public function __construct (ShellAdapter $oShell, array $aConfig)
49: {
50: $this->aProperties = array();
51: $this->oShell = $oShell;
52: $this->aConfig = $aConfig;
53: }
54:
55: /**
56: * Retourne la valeur de la propriété spécifiée (insensible à la casse).
57: *
58: * @param string $sPropertyName propriété dont on recherche la valeur
59: * @return string valeur de la propriété spécifiée.
60: * @throws \UnexpectedValueException si propriété inconnue
61: */
62: public function getProperty ($sPropertyName)
63: {
64: if (! isset($this->aProperties[strtolower($sPropertyName)])) {
65: throw new \UnexpectedValueException("Unknown property '$sPropertyName'!");
66: }
67: return $this->aProperties[strtolower($sPropertyName)];
68: }
69:
70: /**
71: * Initialise ou met à jour la valeur de la propriété spécifiée (insensible à la casse).
72: *
73: * @param string $sPropertyName propriété
74: * @param string $sValue
75: * @return PropertiesInterface $this
76: */
77: public function setProperty ($sPropertyName, $sValue)
78: {
79: $this->aProperties[strtolower($sPropertyName)] = (string)$sValue;
80: return $this;
81: }
82:
83: /**
84: * Charge le fichier INI spécifié en ajoutant ou écrasant ses définitions aux propriétés existantes.
85: * Le nom des propriétés sont insensibles à la casse.
86: *
87: * @param string $sIniPath path du fichier INI à charger
88: * @return PropertiesInterface cette instance
89: * @throws \RuntimeException si erreur de chargement du fichier INI
90: * @throws \UnexpectedValueException si fichier INI introuvable
91: */
92: public function loadConfigIniFile ($sIniPath)
93: {
94: if (! file_exists($sIniPath)) {
95: throw new \UnexpectedValueException("Property file '$sIniPath' not found!");
96: }
97:
98: try {
99: $aRawProperties = parse_ini_file($sIniPath);
100: } catch (\ErrorException $oException) {
101: throw new \RuntimeException("Load property file '$sIniPath' failed: " . $oException->getMessage());
102: }
103:
104: // Normalisation :
105: $aProperties = array();
106: foreach ($aRawProperties as $sProperty => $sValue) {
107: $aProperties[strtolower($sProperty)] = $sValue;
108: }
109:
110: $this->aProperties = array_merge($this->aProperties, $aProperties);
111: return $this;
112: }
113:
114: /**
115: * Charge le fichier shell spécifié en ajoutant ou écrasant ses définitions aux propriétés existantes.
116: * Le nom des propriétés sont insensibles à la casse.
117: *
118: * Format du fichier :
119: * PROPRIETE_1="chaîne"
120: * PROPRIETE_2="chaîne $PROPRIETE_1 chaîne"
121: * ...
122: *
123: * @param string $sConfigShellPath path du fichier shell à charger
124: * @return PropertiesInterface cette instance
125: * @throws \RuntimeException si erreur de chargement du fichier
126: * @throws \UnexpectedValueException si fichier shell introuvable
127: */
128: public function loadConfigShellFile ($sConfigShellPath)
129: {
130: if (! file_exists($sConfigShellPath)) {
131: throw new \UnexpectedValueException("Property file '$sConfigShellPath' not found!");
132: }
133: $sConfigIniPath = tempnam($this->aConfig['dir']['tmp'], 'deploy_configshell2ini_');
134: $sCmd = $this->aConfig['bash_path'] . " '" . $this->aConfig['dir']['inc']
135: . "/cfg2ini.sh' '$sConfigShellPath' '$sConfigIniPath'";
136: $this->oShell->exec($sCmd);
137: $this->loadConfigIniFile($sConfigIniPath);
138: unlink($sConfigIniPath);
139: return $this;
140: }
141: }
142: