Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Symlink.php
Go to the documentation of this file.
1 <?php
7 
12 {
21  public function createDelegate($source, $dest)
22  {
23  $sourcePath = $this->getSourceDir() . '/' . $this->removeTrailingSlash($source);
24  $destPath = $this->getDestDir() . '/' . $this->removeTrailingSlash($dest);
25 
26  if (!is_file($sourcePath) && !is_dir($sourcePath)) {
27  throw new \ErrorException("Could not find path '$sourcePath'");
28  }
29 
30  /*
31 
32  Assume app/etc exists, app/etc/a does not exist unless specified differently
33 
34  OK dir app/etc/a --> link app/etc/a to dir
35  OK dir app/etc/ --> link app/etc/dir to dir
36  OK dir app/etc --> link app/etc/dir to dir
37 
38  OK dir/* app/etc --> for each dir/$file create a target link in app/etc
39  OK dir/* app/etc/ --> for each dir/$file create a target link in app/etc
40  OK dir/* app/etc/a --> for each dir/$file create a target link in app/etc/a
41  OK dir/* app/etc/a/ --> for each dir/$file create a target link in app/etc/a
42 
43  OK file app/etc --> link app/etc/file to file
44  OK file app/etc/ --> link app/etc/file to file
45  OK file app/etc/a --> link app/etc/a to file
46  OK file app/etc/a --> if app/etc/a is a file throw exception unless force is set, in that case rm and see above
47  OK file app/etc/a/ --> link app/etc/a/file to file regardless if app/etc/a existst or not
48 
49  */
50 
51  // Symlink already exists
52  if (is_link($destPath)) {
53  if (realpath(readlink($destPath)) == realpath($sourcePath)) {
54  // .. and is equal to current source-link
55  return true;
56  }
57  unlink($destPath);
58  }
59 
60  // Create all directories up to one below the target if they don't exist
61  $destDir = dirname($destPath);
62  if (!file_exists($destDir)) {
63  mkdir($destDir, 0777, true);
64  }
65 
66  // Handle source to dir linking,
67  // e.g. Namespace_Module.csv => app/locale/de_DE/
68  // Namespace/ModuleDir => Namespace/
69  // Namespace/ModuleDir => Namespace/, but Namespace/ModuleDir may exist
70  // Namespace/ModuleDir => Namespace/ModuleDir, but ModuleDir may exist
71 
72  if (file_exists($destPath) && is_dir($destPath)) {
73  if (basename($sourcePath) === basename($destPath)) {
74  if ($this->isForced()) {
75  $this->rmdirRecursive($destPath);
76  } else {
77  throw new \ErrorException("Target $dest already exists (set extra.magento-force to override)");
78  }
79  } else {
80  $destPath .= '/' . basename($source);
81  }
82  return $this->create($source, substr($destPath, strlen($this->getDestDir())+1));
83  }
84 
85  // From now on $destPath can't be a directory, that case is already handled
86 
87  // If file exists and force is not specified, throw exception unless FORCE is set
88  // existing symlinks are already handled
89  if (file_exists($destPath)) {
90  if ($this->isForced()) {
91  unlink($destPath);
92  } else {
93  throw new \ErrorException("Target $dest already exists and is not a symlink (set extra.magento-force to override)");
94  }
95  }
96 
97  // Windows doesn't allow relative symlinks
98  if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
99  $sourcePath = $this->getRelativePath($destPath, $sourcePath);
100  }
101 
102  // Create symlink
103  if(false === symlink($sourcePath, $destPath)) {
104  throw new \ErrorException("An error occured while creating symlink" . $sourcePath);
105  }
106 
107  // Check we where able to create the symlink
108  if(false === $destPath = readlink($destPath)){
109  throw new \ErrorException("Symlink $destPath points to target $destPath");
110  }
111 
112  return true;
113  }
114 
124  public function getRelativePath($from, $to)
125  {
126  $from = str_replace(array('/./', '//', '\\'), '/', $from);
127  $to = str_replace(array('/./', '//', '\\'), '/', $to);
128 
129  if (is_file($from)) {
130  $from = dirname($from);
131  } else {
132  $from = rtrim($from, '/');
133  }
134 
135  $dir = explode('/', $from);
136  $file = explode('/', $to);
137 
138  while ($file && $dir && ($dir[0] == $file[0])) {
139  array_shift($file);
140  array_shift($dir);
141  }
142 
143  $relativePath = str_repeat('../', count($dir)) . implode('/', $file);
144  return $relativePath;
145  }
146 }
$source
Definition: source.php:23
mkdir($pathname, $mode=0777, $recursive=false, $context=null)
Definition: ioMock.php:25
$relativePath
Definition: get.php:35