support for zend_extension
[pharext/pharext] / src / pharext / Task / Activate.php
1 <?php
2
3 namespace pharext\Task;
4
5 use pharext\Exception;
6 use pharext\ExecCmd;
7 use pharext\Task;
8 use pharext\Tempfile;
9
10 /**
11 * PHP INI activation
12 */
13 class Activate implements Task
14 {
15 /**
16 * @var string
17 */
18 private $cwd;
19
20 /**
21 * @var array
22 */
23 private $inis;
24
25 /**
26 * @var string
27 */
28 private $type;
29
30 /**
31 * @var string
32 */
33 private $php_config;
34
35 /**
36 * @var string
37 */
38 private $sudo;
39
40 /**
41 * @param string $cwd working directory
42 * @param array $inis custom INI or list of loaded/scanned INI files
43 * @param string $type extension or zend_extension
44 * @param string $prefix install prefix, e.g. /usr/local
45 * @param string $common_name PHP programs common name, e.g. php5
46 * @param string $sudo sudo command
47 * @throws \pharext\Exception
48 */
49 public function __construct($cwd, array $inis, $type = "extension", $prefix = null, $common_name = "php", $sudo = null) {
50 $this->cwd = $cwd;
51 $this->type = $type;
52 $this->sudo = $sudo;
53 if (!$this->inis = $inis) {
54 throw new Exception("No PHP INIs given");
55 }
56 $cmd = $common_name . "-config";
57 if (isset($prefix)) {
58 $cmd = $prefix . "/bin/" . $cmd;
59 }
60 $this->php_config = $cmd;
61 }
62
63 /**
64 * @param bool $verbose
65 * @return boolean false, if extension was already activated
66 */
67 public function run($verbose = false) {
68 $extension = basename(current(glob("{$this->cwd}/modules/*.so")));
69
70 if ($this->type === "zend_extension") {
71 $pattern = preg_quote((new ExecCmd($this->php_config))->run(["--extension-dir"])->getOutput() . "/$extension", "/");
72 } else {
73 $pattern = preg_quote($extension, "/");
74 }
75
76 foreach ($this->inis as $file) {
77 $temp = new Tempfile("phpini");
78 foreach (file($file) as $line) {
79 if (preg_match("/^\s*{$this->type}\s*=\s*[\"']?{$pattern}[\"']?\s*(;.*)?\$/", $line)) {
80 return false;
81 }
82 fwrite($temp->getStream(), $line);
83 }
84 }
85
86 /* not found; append to last processed file, which is the main by default */
87 fprintf($temp->getStream(), $this->type . "=%s\n", $extension);
88 $temp->closeStream();
89
90 $path = $temp->getPathname();
91 $stat = stat($file);
92
93 // owner transfer
94 $ugid = sprintf("%d:%d", $stat["uid"], $stat["gid"]);
95 $cmd = new ExecCmd("chown", $verbose);
96 if (isset($this->sudo)) {
97 $cmd->setSu($this->sudo);
98 }
99 $cmd->run([$ugid, $path]);
100
101 // permission transfer
102 $perm = decoct($stat["mode"] & 0777);
103 $cmd = new ExecCmd("chmod", $verbose);
104 if (isset($this->sudo)) {
105 $cmd->setSu($this->sudo);
106 }
107 $cmd->run([$perm, $path]);
108
109 // rename
110 $cmd = new ExecCmd("mv", $verbose);
111 if (isset($this->sudo)) {
112 $cmd->setSu($this->sudo);
113 }
114 $cmd->run([$path, $file]);
115
116 return true;
117 }
118 }