title: Plupload : error “code”: 100, “message”: "Failed to open temp directory
body: <p>So I am working on a project with plupload/codeigniter. I have the code for custom upload.php in the controller under a function called upload. The javascript for plupload is embedded in the view. But I have tried several variations on the $targetDir without success.</p>
  
  <p>The script can't open the temp directory. I tried to CHMOD 755 on the directories without success. Its still on a local enviroment on my Mac.</p>
  
  <pre><code>function upload() {
  
      // HTTP headers for no cache etc
      header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
      header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
      header("Cache-Control: no-store, no-cache, must-revalidate");
      header("Cache-Control: post-check=0, pre-check=0", false);
      header("Pragma: no-cache");
  
      // Settings
      //$targetDir = SITE_DIR . 'nfsopslag/klachten/';
      //$targetDir = SITE_WEB_DIR . 'nfsopslag/klachten/';
      //$targetDir = '..'. SITE_WEB_DIR . 'nfsopslag/klachten/';
      $targetDir = "../../../nfsopslag/klachten";
  
      $cleanupTargetDir = false; // Remove old files
      $maxFileAge = 5 * 3600; // Temp file age in seconds
  
      // 5 minutes execution time
      @set_time_limit(5 * 60);
  
      // Uncomment this one to fake upload time
      // usleep(5000);
  
      // Get parameters
      $chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
      $chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0;
      $fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
  
      // Clean the fileName for security reasons
      $fileName = preg_replace('/[^\w\._]+/', '_', $fileName);
  
      // Make sure the fileName is unique but only if chunking is disabled
      if ($chunks &lt; 2 &amp;&amp; file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName)) {
          $ext = strrpos($fileName, '.');
          $fileName_a = substr($fileName, 0, $ext);
          $fileName_b = substr($fileName, $ext);
  
          $count = 1;
          while (file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName_a . '_' . $count . $fileName_b))
              $count++;
  
          $fileName = $fileName_a . '_' . $count . $fileName_b;
      }
  
      $filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName;
  
      // Create target dir
      if (!file_exists($targetDir))
          @mkdir($targetDir);
  
      // Remove old temp files    
      if ($cleanupTargetDir &amp;&amp; is_dir($targetDir) &amp;&amp; ($dir = opendir($targetDir))) {
          while (($file = readdir($dir)) !== false) {
              $tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file;
  
              // Remove temp file if it is older than the max age and is not the current file
              if (preg_match('/\.part$/', $file) &amp;&amp; (filemtime($tmpfilePath) &lt; time() - $maxFileAge) &amp;&amp; ($tmpfilePath != "{$filePath}.part")) {
                  @unlink($tmpfilePath);
              }
          }
  
          closedir($dir);
      } else
          die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}');
  
  
      // Look for the content type header
      if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
          $contentType = $_SERVER["HTTP_CONTENT_TYPE"];
  
      if (isset($_SERVER["CONTENT_TYPE"]))
          $contentType = $_SERVER["CONTENT_TYPE"];
  
      // Handle non multipart uploads older WebKit versions didn't support multipart in HTML5
      if (strpos($contentType, "multipart") !== false) {
          if (isset($_FILES['file']['tmp_name']) &amp;&amp; is_uploaded_file($_FILES['file']['tmp_name'])) {
              // Open temp file
              $out = fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab");
              if ($out) {
                  // Read binary input stream and append it to temp file
                  $in = fopen($_FILES['file']['tmp_name'], "rb");
  
                  if ($in) {
                      while ($buff = fread($in, 4096))
                          fwrite($out, $buff);
                  } else
                      die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
                  fclose($in);
                  fclose($out);
                  @unlink($_FILES['file']['tmp_name']);
              } else
                  die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
          } else
              die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
      } else {
          // Open temp file
          $out = fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab");
          if ($out) {
              // Read binary input stream and append it to temp file
              $in = fopen("php://input", "rb");
  
              if ($in) {
                  while ($buff = fread($in, 4096))
                      fwrite($out, $buff);
              } else
                  die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
  
              fclose($in);
              fclose($out);
          } else
              die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
      }
  
      // Check if file has been uploaded
      if (!$chunks || $chunk == $chunks - 1) {
          // Strip the temp .part suffix off 
          rename("{$filePath}.part", $filePath);
  
      }
  
      // Return JSON-RPC response
      //die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}');
      die('{"jsonrpc" : "2.0", "result" : null, "id" : "id", "cleanFileName" : "'.$fileName.'"}');
  
  }
  </code></pre>
  
  <p>Mostly its the standard code of custom upload of Plupload. It used to work with $targetDir = "../../../nfsopslag/klachten"; when I had the code outside the controller but after migrating it to the development environment that didn't work anymore.</p>
  
  <p>I tried searching it online but didn't find a sollution. So I am stuck on this. Anyone got ideas or suggestions?</p>