phar exclude directories when creating tar archive - php

I want to create a tar archive in a PHP script using the built-in PharData class.
I want the tar archive to represent a directory so I thought of using PharData::buildFromDirectory() to do that. Unfortunately the directory also is a git repository and has a .git folder in it which is much bigger than the directory itself.
So I need to remove that .git directory (ideally also the .idea directory...) from the archive because it would bloat it unnecessarily.
What I tried so far:
Using a regular expression to filter the directory out:
$archive->buildFromDirectory("..", "#^(?!.git).+#");
Which didn't work.
Using PharData::delete(), but unfortunately that seems to only delete a file and not a directory.
So, what is the best way to do what I want?

I've seen the following used to exclude git directories using a negative lookahead:
$phar->buildFromDirectory(__DIR__, '/^((?!\.git).)*$/');

The problem with your regex is that the full path of the file gets matched, not only the directory (basename). Thus you cannot filter out the .git directory itself.
Using a character class negation ([^.][^g][^i][^t]) does also not help because there are parts of the path that do match this regex, so the path matches anyway.
This means you can use positive matches only.
You could use Phar::buildFromIterator and then use RecursiveFilterIterator to filter out the files.
There you can define your own matching method that filters correctly.

Related

Exclude a specific file Loader.php from Zend folder under vendor folder

Below is the entry I added in .gitignore to exclude Load.php file so that any change to this file is tracked. I don't seem to find the mistake in my rules. Please help me figure it out.
Path to the file: public_html/vendor/magento/zendframework1/library/Zend
/public_html/vendor
!/public_html/vendor/magento
/public_html/vendor/magento/*
!/public_html/vendor/magento/zendframework1
/public_html/vendor/magento/zendframework1/*
!/public_html/vendor/magento/zendframework1/library
/public_html/vendor/magento/zendframework1/library/*
!/public_html/vendor/magento/zendframework1/library/Zend
/public_html/vendor/magento/zendframework1/library/Zend/*
!public_html/vendor/magento/zendframework1/library/Zend/Loader.php
Add at least !/public_html/vendor/*/:
/public_html/vendor/*
!/public_html/vendor/*/
!public_html/vendor/magento/zendframework1/library/Zend/Loader.php
(no trailing slash after Loader.php, since it is a file, not a folder)
If you do not whitelist folders (here, subfolders of vendor/), you won't be able to exclude files, since the parent folders are ignored.
The general rule is:
It is not possible to re-include a file if a parent directory of that file is excluded.
Double-check with git check-ignore -v -- path/to/file
Also, make sure the file was not already tracked:
cd /path/to/repository
git rm --cached -- public_html/vendor/magento/zendframework1/library/Zend/Loader.php

Creating directories with regex same in url structure

I will mass download thousands of images from a server.
My problem is : filenames are same and they are located in different directories.
Ex:
http://domain.com/images/upload/2014/09/SKU00123/1.jpg
http://domain.com/images/upload/2014/09/SKU1501/1.jpg
I want to download them with the same directory structure.
c:\images\upload\2014\09\SKU00123\1.jpg
I can take the file name with basename command but i couldn't find a way to get the directory structure. I need php to create directories and save the files to that destination.
Is there a way to change the url structure to directory structure? Maybe with regex?
For the next time, please show us some PHP code. Have you already tried something?!
...You can easily do this in 2 steps:
Use parse_url to find the path(/images/upload/2014/etc..) of the URL.
Use mkdir with the recursive parameter to create these directories on your own system.

PharData zip to include empty folders

I am zipping entire server content(for backup purposes) via php / PharData:
$phar = new PharData(SYS_ROOT.'/project.zip');
$phar->buildFromDirectory(SYS_ROOT.'/');
SYS_ROOT is constant defining path to web root (. dot in this case). Everything works fine except for missing empty folders in the resulting zip. The folders are necessary.
I tought about Phar::addEmptyDir, but that would require another iteration through the folders to determine which are empty. Tried recursivedirectoryiterator to no avail(also skipped empty folders) as well :(
I've never used this but looking at the documentation it says the following:
Phar::buildFromDirectory — Construct a phar archive from the files within a directory.
Which means that it is behaving as expected. However I think you could use buildFromIterator and then also compress since this is for backups I think I'd go with that one.

Skip "root" directory when extracting using ZipArchive class?

I am attempting to use the ZipArchive class to unzip the contents of a zip containing a GitHub repository.
When you download a zip from GitHub, the zip contains a folder at the root of the zip named something like "project-2302392-20230"... Then within that folder are the actual contents of the repository.
Is it possible extract everything within that project folder without extracting the folder itself?
Here's one way to figure out the name of the unique top directory of the github zip archive.
use getArchiveComment() to get the ziparchive comment.
use strpos to strip away all characters except the first 7 and also add the git username and repo name like so '/USER-REPO-'.substr($comment, 0, 7);
You could also use regex, scandir, and a number of other ways.

Creating a file/folder structure and zipping it up?

I have a directory of image files and I need a php script or shell script that will rename them, create a structure of nested directories, and then insert each image into a specified place in the directory hierarchy. Ideally I would just specify a parent directory for each file and a parent directory for each directory and it would build it. And then finally, I need the script to zip up the whole thing.
There's probably not an existing php class that will do all this for me, but if anyone knows of a php class or other script available online that would handle a lot of this logic that would be great.
I know its not PHP, but you might want to investigate something like this:
a shell script for renaming files (your dialect may vary, but the man pages are very helpful).
foreach img (/path/to/directory/*.jpg)
set newimg= `echo $img | sed 's,path/to/directory/(.+)\.jpg,new/path/$1newname.jpg/,'`
cp img newimg
end
If all the files in a particular directory are going to one location, something like the above might work. Essentially it loops through the target directory getting the names of the files that have a .jpg (or whatever) extension. Then it takes those names, including their path and subs in the new directory path and some change to the original file change. I've used , for the separator in the substitution because escaping all those path separators is a pain. Lastly, it copies the old file to the new location.
Since your directory needs are probably more complex than a hardcoded path allows for, you can include a line to parse your filepath/filename and determine what its target path should be; and use that in the substitution.
A snippet for creating a directory tree in one go can be found here.
You may also decide that find is a better fit for this than foreach because it can descend a directory structure as far as you like.

Categories