mirror of
https://github.com/moodle/moodle.git
synced 2025-03-21 16:10:15 +01:00
Merge branch 'MDL-70318-master' of https://github.com/ilyatregubov/moodle
This commit is contained in:
commit
2624530b36
46
lib/plist/CODE_OF_CONDUCT.md
Normal file
46
lib/plist/CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,46 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@teclib.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
380
lib/plist/CONTRIBUTING.md
Normal file
380
lib/plist/CONTRIBUTING.md
Normal file
@ -0,0 +1,380 @@
|
||||
# How to contribute to Teclib' CFPropertyList
|
||||
|
||||
Welcome to our ever-growing community :octocat:!
|
||||
|
||||
Teclib’ is an open source software editor that offers a vast range of fully integrated open source technology packages, to better respond to business needs.
|
||||
|
||||
We are more than happy to accept external contributions to the project in the form of feedback, translations, bug reports, and even better, pull requests.
|
||||
|
||||
We present you here the guidelines to start contributing in any of the Teclib' projects.
|
||||
|
||||
# <a name="top"></a>Table of contents
|
||||
|
||||
- 1 [See what’s going on](#1)
|
||||
- 1.1 [Issue Dashboard](#1.1)
|
||||
- 1.2 [Pull Request Dashboard](#1.2)
|
||||
- 2 [Assistance](#2)
|
||||
- 2.1 [Contact us](#2.1)
|
||||
- 2.2 [Customers Assistance](#2.2)
|
||||
- 3 [Feature Requests](#3)
|
||||
- 3.1 [Requirement for a Feature Request](#3.1)
|
||||
- 3.1.1 [Major Feature Request](#3.1.1)
|
||||
- 3.1.2 [Minor Feature Request](#3.1.2)
|
||||
- 3.2 [Request a New Feature](#3.2)
|
||||
- 4 [Submitting](#4)
|
||||
- 4.1 [How to Submit an Issue or Bugs](#4.1)
|
||||
- 4.1.1 [Check for Past Issues or Bugs](#4.1.1)
|
||||
- 4.1.2 [Try to Reproduce It!](#4.1.2)
|
||||
- 4.1.3 [Isolate the Problem](#4.1.3)
|
||||
- 4.1.4 [Information Needed for the Report](#4.1.4)
|
||||
- 4.1.5 [Submit an Issue](#4.1.5)
|
||||
- 4.2 [How to Create a Pull Request (PR)](#4.2)
|
||||
- 4.2.1 [Create a Branch and Naming it](#4.2.1)
|
||||
- 4.2.2 [Make Changes](#4.2.2)
|
||||
- 4.2.3 [Commit Your Changes](#4.2.3)
|
||||
- 4.2.3.1 [Rules to Follow](#4.2.3.1)
|
||||
- 4.2.3.2 [Commit Format](#4.2.3.2)
|
||||
- 4.2.3.2.1 [Header: Writing a `type`](#4.2.3.2.1)
|
||||
- 4.2.3.2.2 [Header: Writing the `(optional scope)`](#4.2.3.2.2 )
|
||||
- 4.2.3.2.3 [Header: Writing a `description`](#4.2.3.2.3)
|
||||
- 4.2.3.2.4 [Header Lenght](#4.2.3.2.4)
|
||||
- 4.2.3.2.5 [Writing the `optional body`](#4.2.3.2.5)
|
||||
- 4.2.3.2.6 [Writing the `optional footer`](#4.2.3.2.6)
|
||||
- 4.2.3.3 [Commit Examples](#4.2.3.3)
|
||||
- 4.2.4 [Push your Changes](#4.2.4)
|
||||
- 4.2.5 [Create a Pull Request](#4.2.5)
|
||||
- 4.2.5.1 [How to Write a Title for a Pull Request](#4.2.5.1)
|
||||
- 4.2.5.2 [Before Send a Pull Request](#4.2.5.2)
|
||||
- 4.2.5.3 [How We Check your Submission](#4.2.5.3)
|
||||
- 4.2.5.3.1 [Status Check](#4.2.5.3.1)
|
||||
- 4.2.5.3.2 [App/Bots List](#4.2.5.3.2)
|
||||
- 4.2.6 [How to proceed with suggestions](#4.2.6)
|
||||
- 5 [What to do next?](#5)
|
||||
- 6 [Coding Rules](#6)
|
||||
|
||||
# <a name="1"></a> 1. See what's going on! [:top:](#top)
|
||||
|
||||
## <a name="1.1"></a> 1.1 Issue Dashboard
|
||||
If you want to know all the issues we're dealing with right now, take a look at our [Issue Dashboard](https://github.com/TECLIB/CFPropertyList/issues) and look for areas in which you can help.
|
||||
|
||||
|
||||
## <a name="1.2"></a> 1.2 Pull Request Dashboard
|
||||
If you want to give us a hand solving issues then great, take a look at our [Pull Request Dashboard](https://github.com/TECLIB/CFPropertyList/pulls) and check for an open or closed PR. We don’t want to duplicate efforts.
|
||||
|
||||
# <a name="2"></a> 2. Assistance [:top:](#top)
|
||||
|
||||
## <a name="2.1"></a> 2.1 Contact us
|
||||
You can contact us through any of our channels, check our [Contact section](http://www.teclib-edition.com/en/contact-us/)
|
||||
|
||||
## <a name="2.2"></a> 2.2 Customers Assistance
|
||||
Use our official [support channel](https://support.teclib.com/).
|
||||
|
||||
# <a name="3"></a> 3. Feature Requests [:top:](#top)
|
||||
|
||||
## <a name="3.1"></a> 3.1 Requirement for a Feature Request
|
||||
If you like to _implement_ a new feature please [submit an Issue](https://github.com/TECLIB/CFPropertyList/issues/new) with a proposal, so we can be sure it's relevant.
|
||||
|
||||
### <a name="3.1.1"></a> 3.1.1 Major Feature Request
|
||||
For a major new feature request, [open an Issue](https://github.com/TECLIB/CFPropertyList/issues/new) and outline your proposal so it can be discussed.
|
||||
|
||||
### <a name="3.1.2"></a> 3.1.2 Minor Feature Request
|
||||
For a minor new feature request, you can craft it and directly [submit it as a Pull Request](https://github.com/TECLIB/CFPropertyList/pulls), we'll take care of it.
|
||||
|
||||
## <a name="3.2"></a> 3.2 Request a New Feature
|
||||
You can request a new feature by [submitting an Issue](https://github.com/TECLIB/CFPropertyList/issues/new)
|
||||
|
||||
# <a name="4"></a> 4. Submitting [:top:](#top)
|
||||
|
||||
## <a name="4.1"></a> 4.1 How to Submit an Issue or Bugs
|
||||
|
||||
A good Issue/Bug report shouldn't leave others needing to chase you up for more information. Please try to be as detailed as possible in your report. What is your environment? What steps will reproduce the issue? What would you expect to be the outcome? All these details will help people to fix any potential bugs.
|
||||
|
||||
A bug is a _demonstrable problem_ that is caused by the code in the repository. Good bug reports are extremely helpful, here are steps to follow to build a good one:
|
||||
|
||||
### <a name="4.1.1"></a> 4.1.1 Check for Past Issues or Bugs
|
||||
Before submitting the issue please check the [Issue Tracker](https://github.com/TECLIB/CFPropertyList/issues/), maybe the issue/bug was already reported by another contributor. By doing this you help us maximize the effort spent on solving problems and the addition of new features.
|
||||
|
||||
### <a name="4.1.2"></a> 4.1.2 Try to Reproduce It!
|
||||
Try to reproduce this issue/bug using the latest `develop` branch in the repository [Check it here](https://github.com/TECLIB/CFPropertyList/branches).
|
||||
|
||||
### <a name="4.1.3"></a> 4.1.3 Isolate the Problem
|
||||
Ideally, create a reduced test case. We prefer bug reports with small, portable test cases.
|
||||
|
||||
### <a name="4.1.4"></a> 4.1.4 Information Needed for the Report
|
||||
We require the following information:
|
||||
|
||||
* :warning: **Observed Results:** A brief description of the problem.
|
||||
* :mag_right: **What steps will reproduce the issue?:** If suitable, including the steps required to reproduce the bug.
|
||||
* :boom: **Expected Results:** What did you expect to happen?
|
||||
|
||||
### <a name="4.1.5"></a> 4.1.5 Submit an Issue. :rocket:
|
||||
Having all data at hand, file the new issue by filling out our [Issue form](https://github.com/TECLIB/CFPropertyList/issues/new).
|
||||
|
||||
**— That's it! :tada:**
|
||||
|
||||
## <a name="4.2"></a> 4.2 How to Create a Pull Request (PR)
|
||||
|
||||
Before submitting your Pull Request check for an open or closed PR that relates to your submission. We don't want to duplicate efforts.
|
||||
|
||||
### <a name="4.2.1"></a> 4.2.1 Create a Branch and Naming it
|
||||
|
||||
The project is organized according to the branch model [Git Flow.](http://nvie.com/posts/a-successful-git-branching-model/) Create a new branch before committing any changes. A _branch is a parallel version of a repository._ It is contained within the repository but does not affect the **`primary or master`** branch.
|
||||
|
||||
:heavy_exclamation_mark: **Branch Name Format: `feature/my-killer-feature`**.
|
||||
|
||||
:no_entry_sign: **Important:** Do not commit to our default **`develop`** branch. Name it anything _except master, develop, release-*, or hotfix-*_. We'll use **`created-branch`** an example.
|
||||
|
||||
### <a name="4.2.2"></a> 4.2.2 Make Changes
|
||||
|
||||
Make your changes in your **newly created** branch.
|
||||
|
||||
```console
|
||||
git checkout -b feature/created-branch develop
|
||||
```
|
||||
|
||||
### <a name="4.2.3"></a> 4.2.3 Commit Your Changes
|
||||
A commit, or "revision", is an individual change to a file (or set of files). It's like when you save a file, except with Git, every time you save it creates a unique ID (a.k.a. the "SHA" or "hash") that allows you to keep a record of what changes were made when and by who. Commits usually contain a commit message which is a brief description of what changes were made.
|
||||
|
||||
### <a name="4.2.3.1"></a> 4.2.3.1 Rules to Follow
|
||||
For commits, we follow the [Conventional Commit](http://conventionalcommits.org/). This leads to **more readable messages** that are easy to follow when looking through the project history. But also, we use the git commit messages to **automatically generate changelogs** from these messages.
|
||||
|
||||
### <a name="4.2.3.2"></a> 4.2.3.2 Commit Format
|
||||
Each commit message consists of a **header**, a **body**, and a **footer**. The header has a special
|
||||
format that includes a **type**, a **scope**, and a **description**:
|
||||
|
||||
**:warning: Important:** Please avoid generic terms.
|
||||
|
||||
The commit message should be structured as follows:
|
||||
|
||||
```console
|
||||
type(optional scope): description
|
||||
<blank line>
|
||||
optional body
|
||||
<blank line>
|
||||
optional footer
|
||||
```
|
||||
|
||||
### <a name="4.2.3.2.1"></a> 4.2.3.2.1 Header: Writing a `type`
|
||||
Commits must be prefixed with a type, which consists of a verb, **feat, fix, build,** followed by a colon and space.
|
||||
|
||||
**Your options:**
|
||||
|
||||
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm).
|
||||
* **ci**: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs).
|
||||
* **docs**: Documentation only changes.
|
||||
* **feat**: A new feature.
|
||||
* **fix**: A bug fix.
|
||||
* **perf**: A code change that improves performance.
|
||||
* **refactor**: A code change that neither fixes a bug or adds a feature.
|
||||
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc).
|
||||
* **test**: Adding missing tests or correcting existing tests.
|
||||
|
||||
---
|
||||
>**Example for `type`:**
|
||||
>:point_right:feat:point_left:(parser): add ability to parse arrays
|
||||
---
|
||||
|
||||
### <a name="4.2.3.2.2"></a> 4.2.3.2.2 Header: Writing the `(optional scope)`
|
||||
Refers to the extent, subject matter or contextual information about your changes. A scope is a phrase describing the file modified or a section of the codebase, it’s always enclosed in parenthesis.
|
||||
|
||||
---
|
||||
> **Example for a `(optional scope)`:**
|
||||
> feat:point_right:(parser):point_left:: add ability to parse arrays
|
||||
---
|
||||
|
||||
### <a name="4.2.3.2.3"></a> 4.2.3.2.3 Header: Writing a `description`
|
||||
A description must immediately follow the **`type(optional scope):`** The description is a short description of the commit.
|
||||
|
||||
**Important**
|
||||
* About commit character length, keep it concise and don't write more than **50 characters**.
|
||||
* Use the imperative present tense: change, make, add, update, fix, etc; Do not use changed, changes, added, fixes, fixed, etc.
|
||||
* Don't capitalize the first letter.
|
||||
* Do not use a dot (.) at the end.
|
||||
|
||||
---
|
||||
>**Example for `<description>`**:
|
||||
>feat(parser)::point_right:add ability to parse arrays:point_left:
|
||||
---
|
||||
|
||||
### <a name="4.2.3.2.4"></a> 4.2.3.2.4 Header Lenght
|
||||
The **header** cannot be longer than 100 characters. This allows the message to be easier to read on GitHub as well as in various git tools.
|
||||
|
||||
### <a name="4.2.3.2.5"></a> 4.2.3.2.5 Writing the `optional body`
|
||||
The body should include the motivation for the change and contrast this with previous behavior.
|
||||
|
||||
---
|
||||
>**Example for `optional body`**:
|
||||
```console
|
||||
fix orthography
|
||||
remove out of date paragraph
|
||||
fix broken links
|
||||
```
|
||||
---
|
||||
|
||||
### <a name="4.2.3.2.6"></a> 4.2.3.2.6 Writing the `optional footer`
|
||||
The `<optional footer>` should contain a [closing reference to an issue](https://help.github.com/articles/closing-issues-using-keywords/) if any.
|
||||
|
||||
For example, to close an issue numbered **`123`**, you could use the phrases **`Closes #123`** in your pull request description or commit message. Once the branch is merged into the default branch, the issue will close.
|
||||
|
||||
---
|
||||
>**Example for `optional footer`**:
|
||||
>:point_right:Closes #123:point_left:
|
||||
---
|
||||
|
||||
### <a name="4.2.3.3"></a> 4.2.3.3 Commit Examples
|
||||
:shit:
|
||||
**Bad**
|
||||
|
||||
```console
|
||||
docs(readme): fix orthography, remove out of date paragraph and fix broken links
|
||||
```
|
||||
|
||||
:+1:
|
||||
**Good**
|
||||
|
||||
```console
|
||||
docs(readme): document design improvement change content
|
||||
|
||||
fix orthography
|
||||
remove out of date paragraph
|
||||
fix broken links
|
||||
```
|
||||
|
||||
### <a name="4.2.4"></a> 4.2.4 Push your Changes
|
||||
Pushing refers to **sending your committed changes to a remote repository**, such as a repository hosted on GitHub. For instance, if you change something locally, you'd want to then push those changes so that others may access them.
|
||||
|
||||
After working on your changes you need to Push it (upload) your **newly created branch** to GitHub
|
||||
|
||||
```console
|
||||
git push origin feature/created-branch
|
||||
```
|
||||
|
||||
### <a name="4.2.5"></a> 4.2.5 Create a Pull Request
|
||||
|
||||
Pull requests or PR are **proposed changes** to a repository submitted by a user and accepted or rejected by a repository's collaborators.
|
||||
|
||||
After all the work being pushed to the newly created branch, In GitHub, send a pull request to our [repository.](https://github.com/TECLIB/CFPropertyList/pulls)
|
||||
|
||||
### <a name="4.2.5.1"></a> 4.2.5.1 How to Write a Title for a Pull Request
|
||||
Pull Request should be named in reference to the main fix or feature you provide; minor information can be added to the description. Please be specific and don't use generic terms.
|
||||
|
||||
**:warning: Important:** Please avoid generic terms.
|
||||
|
||||
:straight_ruler:
|
||||
**Title Length:** Keep it concise and don't write more than **50 characters** in the title.
|
||||
|
||||
:construction:
|
||||
**For Work in Progress (WIP):** If you don’t want your PR to be merged accidentally, add the word "wip" or "WIP" to its title and the [WIP bot](https://github.com/apps/wip) will set its status to error.
|
||||
|
||||
---
|
||||
>**Example for `Titles for work in progress (WIP):`**
|
||||
>:point_right:WIP Added a Table of Content for the Contributing Guideline Document.:point_left:
|
||||
---
|
||||
|
||||
:white_check_mark:
|
||||
**Finalized Work:** If you are done with your work and want it to be merged, just write a descriptive title with no more than 50 characters.
|
||||
|
||||
---
|
||||
>**Example for `Titles for Finalized Work:`**
|
||||
>:point_right:Added a Table of Content for the Contributing Guideline Document.:point_left:
|
||||
---
|
||||
|
||||
### <a name="4.2.5.2"></a> 4.2.5.2 Before Send a Pull Request
|
||||
|
||||
**1 - Pull Request Description:** Write a description about the changes, we provide a [template](https://github.com/TECLIB/CFPropertyList/community) for Pull Request descriptions. When you're creating a Pull Request it'll be shown automatically. Just fill it out and you're done.
|
||||
|
||||
**2 - Choose the right label**: Look at the [list of available labels.](https://github.com/TECLIB/CFPropertyList/issues/labels)
|
||||
|
||||
**3 - Smash that button!** Press that _Create Pull Request_ button and you're done.
|
||||
|
||||
**— That's it! :tada:**
|
||||
|
||||
### <a name="4.2.5.3"></a> 4.2.5.3 How We Check your Submission
|
||||
|
||||
#### <a name="4.2.5.3.1"></a> 4.2.5.3.1 Status Check :rotating_light:
|
||||
|
||||
Required status checks ensure us that all required tests are passing before collaborators can make changes to a protected branch. We enforce status checks before a branch is merged.
|
||||
|
||||
The type of required status check we choose is _Loose_, not all of them are required but some of them determines whether your changes will be reviewed or not. Some of them are here on this list, although, some of them may not be implemented in all repositories:
|
||||
|
||||
#### <a name="4.2.5.3.2"></a> 4.2.5.3.2 App/Bots List :traffic_light:
|
||||
|
||||
**WIP:** Refers to Work In Progress, this app helps you to prevent your PR to be merged accidentally, add the word "wip" or "WIP" to its title and WIP bot will set its status to error. When you write WIP in the PR title it means that your changes are still in progress or unfinished, so it won't be reviewed until the WIP is removed.
|
||||
|
||||
_WIP: Maintainers: Required / Contributors: Required_
|
||||
|
||||
**AccessLint:** When a pull request is opened, AccessLint reviews the changes and comments with any new accessibility issues, giving you quick, timely, and targeted feedback, before code goes live.
|
||||
|
||||
_AccessLint: Maintainers: Required / Contributors: Required_
|
||||
|
||||
**commitlint:** Runs commitlint against all commits of new or edited pull requests and sets an appropriate status check.
|
||||
|
||||
_commitlint: Maintainers: Required / Contributors: Required_
|
||||
|
||||
**DCO:** This App enforces the Developer Certificate of Origin (DCO) on Pull Requests. It requires all commit messages to contain the Signed-off-by line with an email address that matches the commit author.
|
||||
|
||||
_DCO: Maintainers: Required / Contributors: Optional_
|
||||
|
||||
**DEP:** A Github App that helps to manage Pull Request dependencies. That App works similar to typical CI services ( e.g Travis) but instead of running a test suite, It will check whether a pull request dependencies are resolved.
|
||||
|
||||
_DEP: Maintainers: Required / Contributors: Required_
|
||||
|
||||
**ci/circleci build:** CircleCI acts as a platform for both Continuous Integration and Continuous Deployment. If your tests pass, then you can deploy your code to development, staging, production, or other environments.
|
||||
|
||||
_ci/circleci build: Maintainers: Required / Contributors: Required_
|
||||
|
||||
**continuous-integration/travis-ci/push(and pr):** An automatic construction of the requested changes is carried out and the tests are executed automatically.
|
||||
|
||||
_continuous-integration/travis-ci/push(and pr): Maintainers: Required / Contributors: Required_
|
||||
|
||||
### <a name="4.2.6"></a> 4.2.6 How to proceed with suggestions
|
||||
|
||||
If we suggest changes then:
|
||||
* Make the required updates.
|
||||
* Re-run the test suites to ensure tests are still passing.
|
||||
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
|
||||
|
||||
```shell
|
||||
git rebase develop -i
|
||||
git push -f
|
||||
```
|
||||
:warning:
|
||||
**Remove the WIP label:** When a PR is ready for review, remove the prefix WIP in the PR title.
|
||||
|
||||
# 5. <a name="5"></a> What to do next? [:top:](#top)
|
||||
|
||||
After your pull request is merged, you can safely delete your branch and pull the changes
|
||||
from the main (upstream) repository:
|
||||
|
||||
* Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:
|
||||
|
||||
```shell
|
||||
git push origin --delete feature/created-branch
|
||||
```
|
||||
|
||||
* Check out the develop branch:
|
||||
|
||||
```shell
|
||||
git checkout develop -f
|
||||
```
|
||||
|
||||
* Delete the local branch:
|
||||
|
||||
```shell
|
||||
git branch -D feature/created-branch
|
||||
```
|
||||
|
||||
* Update develop with the latest upstream version:
|
||||
|
||||
```shell
|
||||
git pull --ff upstream develop
|
||||
```
|
||||
|
||||
# 6. <a name="6"></a> Coding Rules [:top:](#top)
|
||||
|
||||
To ensure consistency throughout the source code, keep these rules in mind as you are working:
|
||||
|
||||
* All features or bug fixes must be tested by one or more specs (unit-tests).
|
||||
* All methods must be documented.
|
||||
|
||||
# Good luck! :tada:
|
@ -1,6 +1,8 @@
|
||||
The MIT License
|
||||
# The MIT License
|
||||
|
||||
Copyright (c) 2009 Christian Kruse, Rodney Rehm
|
||||
Copyright © 2018 Teclib'
|
||||
|
||||
Copyright © 2009 Christian Kruse, Rodney Rehm
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
@ -1,39 +1,66 @@
|
||||
# CFPropertyList
|
||||
|
||||
The PHP implementation of Apple's PropertyList can handle XML PropertyLists as well as binary PropertyLists. It offers functionality to easily convert data between worlds, e.g. recalculating timestamps from unix epoch to apple epoch and vice versa. A feature to automagically create (guess) the plist structure from a normal PHP data structure will help you dump your data to plist in no time.
|
||||

|
||||
|
||||
Note: CFPropertylist was originally hosted on [Google Code](http://code.google.com/p/cfpropertylist/)
|
||||
[](./LICENSE.md)
|
||||
[](https://twitter.com/teclib)
|
||||
[](http://www.repostatus.org/#active)
|
||||
[](https://conventionalcommits.org)
|
||||
|
||||
## Choose Your Favorite Operating System
|
||||
Teclib’ is an open source software editor that offers a vast range of fully integrated open source technology packages, to better respond to business needs.
|
||||
|
||||
Visit our Website [Teclib'](http://www.teclib-edition.com/en/).
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Synopsis](#synopsis)
|
||||
* [Build Status](#build-status)
|
||||
* [Installation](#installation)
|
||||
* [Documentation](#documentation)
|
||||
* [Versioning](#versioning)
|
||||
* [Contact](#contact)
|
||||
* [Contribute](#contribute)
|
||||
* [Copying](#copying)
|
||||
|
||||
## Synopsis
|
||||
|
||||
The PHP implementation of Apple's PropertyList can handle both XML and binary PropertyLists. It offers functionality to easily convert data between worlds, e.g. recalculating timestamps from unix epoch to apple epoch and vice versa. A feature to automagically create (guess) the plist structure from a normal PHP data structure will help you dump your data to plist in no time.
|
||||
|
||||
CFPropertyList does not rely on any "Apple proprietary" components, like plutil. CFPropertyList runs on any Operating System with PHP and some standard extensions installed.
|
||||
|
||||
Although you might want to deliver data to your iPhone application, you might want to run those server side services on your standard Linux (or even Windows) environment, rather than buying an expensive Apple Server. With CFPropertyList you now have the power to provide data from your favorite Operating System.
|
||||
|
||||
## Requirements And Limitations
|
||||
## Build Status
|
||||
|
||||
* requires PHP5.3 (as of CFPropertyList 2.0)
|
||||
* requires either [MBString](http://php.net/mbstring) or [Iconv](http://php.net/iconv)
|
||||
* requires either [BC](http://php.net/bc) or [GMP](http://php.net/gmp) or [phpseclib](http://phpseclib.sourceforge.net/) (see BigIntegerBug for an explanation) - as of CFPropertyList 1.0.1
|
||||
|
||||
## Authors
|
||||
|
||||
- Rodney Rehm <rodney.rehm@medialize.de>
|
||||
- Christian Kruse <cjk@wwwtech.de>
|
||||
- PSR-0 changes by Jarvis Badgley <https://github.com/ChiperSoft/CFPropertyList>
|
||||
|
||||
## License
|
||||
|
||||
CFPropertyList is published under the [MIT License](http://www.opensource.org/licenses/mit-license.php).
|
||||
|**Release channel**|Beta Channel|
|
||||
|:---:|:---:|
|
||||
|[](https://travis-ci.org/TECLIB/CFPropertyList)|[](https://travis-ci.org/TECLIB/CFPropertyList)|
|
||||
|
||||
## Installation
|
||||
|
||||
see [Composer / Packagist](http://packagist.org/packages/rodneyrehm/plist).
|
||||
See or [How to install article](https://teclib.github.io/CFPropertyList/howtos/installation).
|
||||
|
||||
## Related
|
||||
## Documentation
|
||||
|
||||
* [man(5) plist](http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html)
|
||||
* [CFBinaryPList.c](http://www.opensource.apple.com/source/CF/CF-476.15/CFBinaryPList.c)
|
||||
* [CFPropertyList in Ruby](http://rubyforge.org/projects/cfpropertylist/)
|
||||
* [CFPropertyList in Python](https://github.com/bencochran/CFPropertyList)
|
||||
* [plist on Wikipedia](http://en.wikipedia.org/wiki/Plist)
|
||||
We maintain a detailed documentation of the project on the Website, check the Development [Development](https://teclib.github.io/CFPropertyList/) and [How-tos](https://teclib.github.io/CFPropertyList/howtos) sections.
|
||||
|
||||
## Versioning
|
||||
|
||||
In order to provide transparency on our release cycle and to maintain backward compatibility, Flyve MDM is maintained under [the Semantic Versioning guidelines](http://semver.org/). We are committed to following and complying with the rules, the best we can.
|
||||
|
||||
See [the tags section of our GitHub project](https://github.com/TECLIB/CFPropertyList/tags) for changelogs for each release version. Release announcement posts on [the official Teclib' blog](http://www.teclib-edition.com/en/communities/blog-posts/) contain summaries of the most noteworthy changes made in each release.
|
||||
|
||||
## Contact
|
||||
|
||||
You can contact us through any of our channels, check our [Contact section](http://www.teclib-edition.com/en/contact-us/)
|
||||
|
||||
## Contribute
|
||||
|
||||
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our
|
||||
guidelines for [contributing](./CONTRIBUTING.md) and then check out one of our issues in the [Issues Dashboard](https://github.com/TECLIB/CFPropertyList/issues).
|
||||
|
||||
## Copying
|
||||
|
||||
* **Code**: you can redistribute it and/or modify
|
||||
it under the terms of the MIT License ([MIT](https://opensource.org/licenses/MIT)).
|
||||
* **Documentation**: released under Attribution 4.0 International ([CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)).
|
285
lib/plist/classes/CFPropertyList/CFArray.php
Normal file
285
lib/plist/classes/CFPropertyList/CFArray.php
Normal file
@ -0,0 +1,285 @@
|
||||
<?php
|
||||
/**
|
||||
* LICENSE
|
||||
*
|
||||
* This file is part of CFPropertyList.
|
||||
*
|
||||
* The PHP implementation of Apple's PropertyList can handle XML PropertyLists
|
||||
* as well as binary PropertyLists. It offers functionality to easily convert
|
||||
* data between worlds, e.g. recalculating timestamps from unix epoch to apple
|
||||
* epoch and vice versa. A feature to automagically create (guess) the plist
|
||||
* structure from a normal PHP data structure will help you dump your data to
|
||||
* plist in no time.
|
||||
*
|
||||
* Copyright (c) 2018 Teclib'
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @copyright Copyright © 2018 Teclib
|
||||
* @package plist
|
||||
* @license MIT
|
||||
* @link https://github.com/TECLIB/CFPropertyList/
|
||||
* @link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace CFPropertyList;
|
||||
|
||||
use \DOMDocument;
|
||||
use \Iterator;
|
||||
use \ArrayAccess;
|
||||
|
||||
/**
|
||||
* Array Type of CFPropertyList
|
||||
*/
|
||||
class CFArray extends CFType implements Iterator, ArrayAccess
|
||||
{
|
||||
/**
|
||||
* Position of iterator {@link http://php.net/manual/en/class.iterator.php}
|
||||
* @var integer
|
||||
*/
|
||||
protected $iteratorPosition = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Create new CFType.
|
||||
* @param array $value Value of CFType
|
||||
*/
|
||||
public function __construct($value = array())
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CFType's value
|
||||
* <b>Note:</b> this dummy does nothing
|
||||
* @return void
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Add CFType to collection.
|
||||
* @param CFType $value CFType to add to collection, defaults to null which results in an empty {@link CFString}
|
||||
* @return void
|
||||
* @uses $value for adding $value
|
||||
*/
|
||||
public function add(CFType $value = null)
|
||||
{
|
||||
// anything but CFType is null, null is an empty string - sad but true
|
||||
if (!$value) {
|
||||
$value = new CFString();
|
||||
}
|
||||
|
||||
$this->value[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CFType from collection.
|
||||
* @param integer $key Key of CFType to retrieve from collection
|
||||
* @return CFType CFType found at $key, null else
|
||||
* @uses $value for retrieving CFType of $key
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
if (isset($this->value[$key])) {
|
||||
return $this->value[$key];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove CFType from collection.
|
||||
* @param integer $key Key of CFType to removes from collection
|
||||
* @return CFType removed CFType, null else
|
||||
* @uses $value for removing CFType of $key
|
||||
*/
|
||||
public function del($key)
|
||||
{
|
||||
if (isset($this->value[$key])) {
|
||||
unset($this->value[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* S E R I A L I Z I N G
|
||||
************************************************************************************************/
|
||||
|
||||
/**
|
||||
* Get XML-Node.
|
||||
* @param DOMDocument $doc DOMDocument to create DOMNode in
|
||||
* @param string $nodeName For compatibility reasons; just ignore it
|
||||
* @return DOMNode <array>-Element
|
||||
*/
|
||||
public function toXML(DOMDocument $doc, $nodeName = "")
|
||||
{
|
||||
$node = $doc->createElement('array');
|
||||
|
||||
foreach ($this->value as $value) {
|
||||
$node->appendChild($value->toXML($doc));
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert value to binary representation
|
||||
* @param CFBinaryPropertyList The binary property list object
|
||||
* @return The offset in the object table
|
||||
*/
|
||||
public function toBinary(CFBinaryPropertyList &$bplist)
|
||||
{
|
||||
return $bplist->arrayToBinary($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CFType's value.
|
||||
* @return array primitive value
|
||||
* @uses $value for retrieving primitive of CFType
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$a = array();
|
||||
foreach ($this->value as $value) {
|
||||
$a[] = $value->toArray();
|
||||
}
|
||||
return $a;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* I T E R A T O R I N T E R F A C E
|
||||
************************************************************************************************/
|
||||
|
||||
/**
|
||||
* Rewind {@link $iteratorPosition} to first position (being 0)
|
||||
* @link http://php.net/manual/en/iterator.rewind.php
|
||||
* @return void
|
||||
* @uses $iteratorPosition set to 0
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->iteratorPosition = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Iterator's current {@link CFType} identified by {@link $iteratorPosition}
|
||||
* @link http://php.net/manual/en/iterator.current.php
|
||||
* @return CFType current Item
|
||||
* @uses $iteratorPosition identify current key
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->value[$this->iteratorPosition];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Iterator's current key identified by {@link $iteratorPosition}
|
||||
* @link http://php.net/manual/en/iterator.key.php
|
||||
* @return string key of the current Item
|
||||
* @uses $iteratorPosition identify current key
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->iteratorPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment {@link $iteratorPosition} to address next {@see CFType}
|
||||
* @link http://php.net/manual/en/iterator.next.php
|
||||
* @return void
|
||||
* @uses $iteratorPosition increment by 1
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->iteratorPosition++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if {@link $iteratorPosition} addresses a valid element of {@link $value}
|
||||
* @link http://php.net/manual/en/iterator.valid.php
|
||||
* @return boolean true if current position is valid, false else
|
||||
* @uses $iteratorPosition test if within {@link $iteratorKeys}
|
||||
* @uses $iteratorPosition test if within {@link $value}
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return isset($this->value[$this->iteratorPosition]);
|
||||
}
|
||||
|
||||
/************************************************************************************************
|
||||
* ArrayAccess I N T E R F A C E
|
||||
************************************************************************************************/
|
||||
|
||||
/**
|
||||
* Determine if the array's key exists
|
||||
* @param string $key the key to check
|
||||
* @return bool true if the offset exists, false if not
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
|
||||
* @uses $value to check if $key exists
|
||||
* @author Sean Coates <sean@php.net>
|
||||
*/
|
||||
public function offsetExists($key)
|
||||
{
|
||||
return isset($this->value[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a specific key from the CFArray
|
||||
* @param string $key the key to check
|
||||
* @return mixed the value associated with the key; null if the key is not found
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetget.php
|
||||
* @uses get() to get the key's value
|
||||
* @author Sean Coates <sean@php.net>
|
||||
*/
|
||||
public function offsetGet($key)
|
||||
{
|
||||
return $this->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value in the array
|
||||
* @param string $key the key to set
|
||||
* @param string $value the value to set
|
||||
* @return void
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetset.php
|
||||
* @uses setValue() to set the key's new value
|
||||
* @author Sean Coates <sean@php.net>
|
||||
*/
|
||||
public function offsetSet($key, $value)
|
||||
{
|
||||
return $this->setValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsets a value in the array
|
||||
* <b>Note:</b> this dummy does nothing
|
||||
* @param string $key the key to set
|
||||
* @return void
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
|
||||
* @author Sean Coates <sean@php.net>
|
||||
*/
|
||||
public function offsetUnset($key)
|
||||
{
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
74
lib/plist/classes/CFPropertyList/CFBoolean.php
Normal file
74
lib/plist/classes/CFPropertyList/CFBoolean.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* LICENSE
|
||||
*
|
||||
* This file is part of CFPropertyList.
|
||||
*
|
||||
* The PHP implementation of Apple's PropertyList can handle XML PropertyLists
|
||||
* as well as binary PropertyLists. It offers functionality to easily convert
|
||||
* data between worlds, e.g. recalculating timestamps from unix epoch to apple
|
||||
* epoch and vice versa. A feature to automagically create (guess) the plist
|
||||
* structure from a normal PHP data structure will help you dump your data to
|
||||
* plist in no time.
|
||||
*
|
||||
* Copyright (c) 2018 Teclib'
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @copyright Copyright © 2018 Teclib
|
||||
* @package plist
|
||||
* @license MIT
|
||||
* @link https://github.com/TECLIB/CFPropertyList/
|
||||
* @link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace CFPropertyList;
|
||||
|
||||
use \DOMDocument;
|
||||
use \Iterator;
|
||||
use \ArrayAccess;
|
||||
|
||||
class CFBoolean extends CFType
|
||||
{
|
||||
/**
|
||||
* Get XML-Node.
|
||||
* Returns <true> if $value is a true, <false> if $value is false.
|
||||
* @param DOMDocument $doc DOMDocument to create DOMNode in
|
||||
* @param string $nodeName For compatibility reasons; just ignore it
|
||||
* @return DOMNode <true> or <false>-Element
|
||||
*/
|
||||
public function toXML(DOMDocument $doc, $nodeName = "")
|
||||
{
|
||||
return $doc->createElement($this->value ? 'true' : 'false');
|
||||
}
|
||||
|
||||
/**
|
||||
* convert value to binary representation
|
||||
* @param CFBinaryPropertyList The binary property list object
|
||||
* @return The offset in the object table
|
||||
*/
|
||||
public function toBinary(CFBinaryPropertyList &$bplist)
|
||||
{
|
||||
return $bplist->boolToBinary($this->value);
|
||||
}
|
||||
}
|
116
lib/plist/classes/CFPropertyList/CFData.php
Normal file
116
lib/plist/classes/CFPropertyList/CFData.php
Normal file
@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/**
|
||||
* LICENSE
|
||||
*
|
||||
* This file is part of CFPropertyList.
|
||||
*
|
||||
* The PHP implementation of Apple's PropertyList can handle XML PropertyLists
|
||||
* as well as binary PropertyLists. It offers functionality to easily convert
|
||||
* data between worlds, e.g. recalculating timestamps from unix epoch to apple
|
||||
* epoch and vice versa. A feature to automagically create (guess) the plist
|
||||
* structure from a normal PHP data structure will help you dump your data to
|
||||
* plist in no time.
|
||||
*
|
||||
* Copyright (c) 2018 Teclib'
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @copyright Copyright © 2018 Teclib
|
||||
* @package plist
|
||||
* @license MIT
|
||||
* @link https://github.com/TECLIB/CFPropertyList/
|
||||
* @link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace CFPropertyList;
|
||||
|
||||
use \DOMDocument;
|
||||
use \Iterator;
|
||||
use \ArrayAccess;
|
||||
|
||||
class CFData extends CFType
|
||||
{
|
||||
/**
|
||||
* Create new Data CFType
|
||||
* @param string $value data to be contained by new object
|
||||
* @param boolean $already_coded if true $value will not be base64-encoded, defaults to false
|
||||
*/
|
||||
public function __construct($value = null, $already_coded = false)
|
||||
{
|
||||
if ($already_coded) {
|
||||
$this->value = $value;
|
||||
} else {
|
||||
$this->setValue($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CFType's value and base64-encode it.
|
||||
* <b>Note:</b> looks like base64_encode has troubles with UTF-8 encoded strings
|
||||
* @return void
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
// if(function_exists('mb_check_encoding') && mb_check_encoding($value, 'UTF-8')) $value = utf8_decode($value);
|
||||
$this->value = base64_encode($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get base64 encoded data
|
||||
* @return string The base64 encoded data value
|
||||
*/
|
||||
public function getCodedValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base64-decoded CFType's value.
|
||||
* @return mixed CFType's value
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return base64_decode($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get XML-Node.
|
||||
* @param DOMDocument $doc DOMDocument to create DOMNode in
|
||||
* @param string $nodeName For compatibility reasons; just ignore it
|
||||
* @return DOMNode <data>-Element
|
||||
*/
|
||||
public function toXML(DOMDocument $doc, $nodeName = "")
|
||||
{
|
||||
return parent::toXML($doc, 'data');
|
||||
}
|
||||
|
||||
/**
|
||||
* convert value to binary representation
|
||||
* @param CFBinaryPropertyList The binary property list object
|
||||
* @return The offset in the object table
|
||||
*/
|
||||
public function toBinary(CFBinaryPropertyList &$bplist)
|
||||
{
|
||||
return $bplist->dataToBinary($this->getValue());
|
||||
}
|
||||
}
|
145
lib/plist/classes/CFPropertyList/CFDate.php
Normal file
145
lib/plist/classes/CFPropertyList/CFDate.php
Normal file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
/**
|
||||
* LICENSE
|
||||
*
|
||||
* This file is part of CFPropertyList.
|
||||
*
|
||||
* The PHP implementation of Apple's PropertyList can handle XML PropertyLists
|
||||
* as well as binary PropertyLists. It offers functionality to easily convert
|
||||
* data between worlds, e.g. recalculating timestamps from unix epoch to apple
|
||||
* epoch and vice versa. A feature to automagically create (guess) the plist
|
||||
* structure from a normal PHP data structure will help you dump your data to
|
||||
* plist in no time.
|
||||
*
|
||||
* Copyright (c) 2018 Teclib'
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @copyright Copyright © 2018 Teclib
|
||||
* @package plist
|
||||
* @license MIT
|
||||
* @link https://github.com/TECLIB/CFPropertyList/
|
||||
* @link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace CFPropertyList;
|
||||
|
||||
use \DOMDocument;
|
||||
use \Iterator;
|
||||
use \ArrayAccess;
|
||||
|
||||
/**
|
||||
* Date Type of CFPropertyList
|
||||
* Note: CFDate uses Unix timestamp (epoch) to store dates internally
|
||||
*/
|
||||
class CFDate extends CFType
|
||||
{
|
||||
const TIMESTAMP_APPLE = 0;
|
||||
const TIMESTAMP_UNIX = 1;
|
||||
const DATE_DIFF_APPLE_UNIX = 978307200;
|
||||
|
||||
/**
|
||||
* Create new Date CFType.
|
||||
* @param integer $value timestamp to set
|
||||
* @param integer $format format the timestamp is specified in, use {@link TIMESTAMP_APPLE} or {@link TIMESTAMP_UNIX}, defaults to {@link TIMESTAMP_APPLE}
|
||||
* @uses setValue() to convert the timestamp
|
||||
*/
|
||||
public function __construct($value, $format = CFDate::TIMESTAMP_UNIX)
|
||||
{
|
||||
$this->setValue($value, $format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Date CFType's value.
|
||||
* @param integer $value timestamp to set
|
||||
* @param integer $format format the timestamp is specified in, use {@link TIMESTAMP_APPLE} or {@link TIMESTAMP_UNIX}, defaults to {@link TIMESTAMP_UNIX}
|
||||
* @return void
|
||||
* @uses TIMESTAMP_APPLE to determine timestamp type
|
||||
* @uses TIMESTAMP_UNIX to determine timestamp type
|
||||
* @uses DATE_DIFF_APPLE_UNIX to convert Apple-timestamp to Unix-timestamp
|
||||
*/
|
||||
public function setValue($value, $format = CFDate::TIMESTAMP_UNIX)
|
||||
{
|
||||
if ($format == CFDate::TIMESTAMP_UNIX) {
|
||||
$this->value = $value;
|
||||
} else {
|
||||
$this->value = $value + CFDate::DATE_DIFF_APPLE_UNIX;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Date CFType's value.
|
||||
* @param integer $format format the timestamp is specified in, use {@link TIMESTAMP_APPLE} or {@link TIMESTAMP_UNIX}, defaults to {@link TIMESTAMP_UNIX}
|
||||
* @return integer Unix timestamp
|
||||
* @uses TIMESTAMP_APPLE to determine timestamp type
|
||||
* @uses TIMESTAMP_UNIX to determine timestamp type
|
||||
* @uses DATE_DIFF_APPLE_UNIX to convert Unix-timestamp to Apple-timestamp
|
||||
*/
|
||||
public function getValue($format = CFDate::TIMESTAMP_UNIX)
|
||||
{
|
||||
if ($format == CFDate::TIMESTAMP_UNIX) {
|
||||
return $this->value;
|
||||
} else {
|
||||
return $this->value - CFDate::DATE_DIFF_APPLE_UNIX;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get XML-Node.
|
||||
* @param DOMDocument $doc DOMDocument to create DOMNode in
|
||||
* @param string $nodeName For compatibility reasons; just ignore it
|
||||
* @return DOMNode <date>-Element
|
||||
*/
|
||||
public function toXML(DOMDocument $doc, $nodeName = "")
|
||||
{
|
||||
$text = $doc->createTextNode(gmdate("Y-m-d\TH:i:s\Z", $this->getValue()));
|
||||
$node = $doc->createElement("date");
|
||||
$node->appendChild($text);
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert value to binary representation
|
||||
* @param CFBinaryPropertyList The binary property list object
|
||||
* @return The offset in the object table
|
||||
*/
|
||||
public function toBinary(CFBinaryPropertyList &$bplist)
|
||||
{
|
||||
return $bplist->dateToBinary($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a UNIX timestamp from a PList date string
|
||||
* @param string $val The date string (e.g. "2009-05-13T20:23:43Z")
|
||||
* @return integer The UNIX timestamp
|
||||
* @throws PListException when encountering an unknown date string format
|
||||
*/
|
||||
public static function dateValue($val)
|
||||
{
|
||||
//2009-05-13T20:23:43Z
|
||||
if (!preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/', $val, $matches)) {
|
||||
throw new PListException("Unknown date format: $val");
|
||||
}
|
||||
return gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
|
||||
}
|
||||
}
|
232
lib/plist/classes/CFPropertyList/CFDictionary.php
Normal file
232
lib/plist/classes/CFPropertyList/CFDictionary.php
Normal file
@ -0,0 +1,232 @@
|
||||
<?php
|
||||
/**
|
||||
* LICENSE
|
||||
*
|
||||
* This file is part of CFPropertyList.
|
||||
*
|
||||
* The PHP implementation of Apple's PropertyList can handle XML PropertyLists
|
||||
* as well as binary PropertyLists. It offers functionality to easily convert
|
||||
* data between worlds, e.g. recalculating timestamps from unix epoch to apple
|
||||
* epoch and vice versa. A feature to automagically create (guess) the plist
|
||||
* structure from a normal PHP data structure will help you dump your data to
|
||||
* plist in no time.
|
||||
*
|
||||
* Copyright (c) 2018 Teclib'
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @copyright Copyright © 2018 Teclib
|
||||
* @package plist
|
||||
* @license MIT
|
||||
* @link https://github.com/TECLIB/CFPropertyList/
|
||||
* @link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace CFPropertyList;
|
||||
|
||||
use \DOMDocument;
|
||||
use \Iterator;
|
||||
use \ArrayAccess;
|
||||
|
||||
/**
|
||||
* Array Type of CFPropertyList
|
||||
*/
|
||||
class CFDictionary extends CFType implements Iterator
|
||||
{
|
||||
/**
|
||||
* Position of iterator {@link http://php.net/manual/en/class.iterator.php}
|
||||
* @var integer
|
||||
*/
|
||||
protected $iteratorPosition = 0;
|
||||
/**
|
||||
* List of Keys for numerical iterator access {@link http://php.net/manual/en/class.iterator.php}
|
||||
* @var array
|
||||
*/
|
||||
protected $iteratorKeys = null;
|
||||
/**
|
||||
* Create new CFType.
|
||||
* @param array $value Value of CFType
|
||||
*/
|
||||
public function __construct($value = array())
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
/**
|
||||
* Set the CFType's value
|
||||
* <b>Note:</b> this dummy does nothing
|
||||
* @return void
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Add CFType to collection.
|
||||
* @param string $key Key to add to collection
|
||||
* @param CFType $value CFType to add to collection, defaults to null which results in an empty {@link CFString}
|
||||
* @return void
|
||||
* @uses $value for adding $key $value pair
|
||||
*/
|
||||
public function add($key, CFType $value = null)
|
||||
{
|
||||
// anything but CFType is null, null is an empty string - sad but true
|
||||
if (!$value) {
|
||||
$value = new CFString();
|
||||
}
|
||||
$this->value[$key] = $value;
|
||||
}
|
||||
/**
|
||||
* Get CFType from collection.
|
||||
* @param string $key Key of CFType to retrieve from collection
|
||||
* @return CFType CFType found at $key, null else
|
||||
* @uses $value for retrieving CFType of $key
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
if (isset($this->value[$key])) {
|
||||
return $this->value[$key];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Generic getter (magic)
|
||||
* @param integer $key Key of CFType to retrieve from collection
|
||||
* @return CFType CFType found at $key, null else
|
||||
* @link http://php.net/oop5.overloading
|
||||
* @uses get() to retrieve the key's value
|
||||
* @author Sean Coates <sean@php.net>
|
||||
*/
|
||||
public function __get($key)
|
||||
{
|
||||
return $this->get($key);
|
||||
}
|
||||
/**
|
||||
* Remove CFType from collection.
|
||||
* @param string $key Key of CFType to removes from collection
|
||||
* @return CFType removed CFType, null else
|
||||
* @uses $value for removing CFType of $key
|
||||
*/
|
||||
public function del($key)
|
||||
{
|
||||
if (isset($this->value[$key])) {
|
||||
unset($this->value[$key]);
|
||||
}
|
||||
}
|
||||
/************************************************************************************************
|
||||
* S E R I A L I Z I N G
|
||||
************************************************************************************************/
|
||||
/**
|
||||
* Get XML-Node.
|
||||
* @param DOMDocument $doc DOMDocument to create DOMNode in
|
||||
* @param string $nodeName For compatibility reasons; just ignore it
|
||||
* @return DOMNode <dict>-Element
|
||||
*/
|
||||
public function toXML(DOMDocument $doc, $nodeName = "")
|
||||
{
|
||||
$node = $doc->createElement('dict');
|
||||
foreach ($this->value as $key => $value) {
|
||||
$node->appendChild($doc->createElement('key', $key));
|
||||
$node->appendChild($value->toXML($doc));
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
/**
|
||||
* convert value to binary representation
|
||||
* @param CFBinaryPropertyList The binary property list object
|
||||
* @return The offset in the object table
|
||||
*/
|
||||
public function toBinary(CFBinaryPropertyList &$bplist)
|
||||
{
|
||||
return $bplist->dictToBinary($this);
|
||||
}
|
||||
/**
|
||||
* Get CFType's value.
|
||||
* @return array primitive value
|
||||
* @uses $value for retrieving primitive of CFType
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$a = array();
|
||||
foreach ($this->value as $key => $value) {
|
||||
$a[$key] = $value->toArray();
|
||||
}
|
||||
return $a;
|
||||
}
|
||||
/************************************************************************************************
|
||||
* I T E R A T O R I N T E R F A C E
|
||||
************************************************************************************************/
|
||||
/**
|
||||
* Rewind {@link $iteratorPosition} to first position (being 0)
|
||||
* @link http://php.net/manual/en/iterator.rewind.php
|
||||
* @return void
|
||||
* @uses $iteratorPosition set to 0
|
||||
* @uses $iteratorKeys store keys of {@link $value}
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->iteratorPosition = 0;
|
||||
$this->iteratorKeys = array_keys($this->value);
|
||||
}
|
||||
/**
|
||||
* Get Iterator's current {@link CFType} identified by {@link $iteratorPosition}
|
||||
* @link http://php.net/manual/en/iterator.current.php
|
||||
* @return CFType current Item
|
||||
* @uses $iteratorPosition identify current key
|
||||
* @uses $iteratorKeys identify current value
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->value[$this->iteratorKeys[$this->iteratorPosition]];
|
||||
}
|
||||
/**
|
||||
* Get Iterator's current key identified by {@link $iteratorPosition}
|
||||
* @link http://php.net/manual/en/iterator.key.php
|
||||
* @return string key of the current Item
|
||||
* @uses $iteratorPosition identify current key
|
||||
* @uses $iteratorKeys identify current value
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->iteratorKeys[$this->iteratorPosition];
|
||||
}
|
||||
/**
|
||||
* Increment {@link $iteratorPosition} to address next {@see CFType}
|
||||
* @link http://php.net/manual/en/iterator.next.php
|
||||
* @return void
|
||||
* @uses $iteratorPosition increment by 1
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->iteratorPosition++;
|
||||
}
|
||||
/**
|
||||
* Test if {@link $iteratorPosition} addresses a valid element of {@link $value}
|
||||
* @link http://php.net/manual/en/iterator.valid.php
|
||||
* @return boolean true if current position is valid, false else
|
||||
* @uses $iteratorPosition test if within {@link $iteratorKeys}
|
||||
* @uses $iteratorPosition test if within {@link $value}
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return isset($this->iteratorKeys[$this->iteratorPosition]) && isset($this->value[$this->iteratorKeys[$this->iteratorPosition]]);
|
||||
}
|
||||
}
|
83
lib/plist/classes/CFPropertyList/CFNumber.php
Normal file
83
lib/plist/classes/CFPropertyList/CFNumber.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* LICENSE
|
||||
*
|
||||
* This file is part of CFPropertyList.
|
||||
*
|
||||
* The PHP implementation of Apple's PropertyList can handle XML PropertyLists
|
||||
* as well as binary PropertyLists. It offers functionality to easily convert
|
||||
* data between worlds, e.g. recalculating timestamps from unix epoch to apple
|
||||
* epoch and vice versa. A feature to automagically create (guess) the plist
|
||||
* structure from a normal PHP data structure will help you dump your data to
|
||||
* plist in no time.
|
||||
*
|
||||
* Copyright (c) 2018 Teclib'
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @copyright Copyright © 2018 Teclib
|
||||
* @package plist
|
||||
* @license MIT
|
||||
* @link https://github.com/TECLIB/CFPropertyList/
|
||||
* @link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace CFPropertyList;
|
||||
|
||||
use \DOMDocument;
|
||||
use \Iterator;
|
||||
use \ArrayAccess;
|
||||
|
||||
/**
|
||||
* Number Type of CFPropertyList
|
||||
* {@link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists}
|
||||
*/
|
||||
class CFNumber extends CFType
|
||||
{
|
||||
/**
|
||||
* Get XML-Node.
|
||||
* Returns <real> if $value is a float, <integer> if $value is an integer.
|
||||
* @param DOMDocument $doc DOMDocument to create DOMNode in
|
||||
* @param string $nodeName For compatibility reasons; just ignore it
|
||||
* @return DOMNode <real> or <integer>-Element
|
||||
*/
|
||||
public function toXML(DOMDocument $doc, $nodeName = "")
|
||||
{
|
||||
$ret = 'real';
|
||||
if (intval($this->value) == $this->value && !is_float($this->value) && strpos($this->value, '.') === false) {
|
||||
$this->value = intval($this->value);
|
||||
$ret = 'integer';
|
||||
}
|
||||
return parent::toXML($doc, $ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* convert value to binary representation
|
||||
* @param CFBinaryPropertyList The binary property list object
|
||||
* @return The offset in the object table
|
||||
*/
|
||||
public function toBinary(CFBinaryPropertyList &$bplist)
|
||||
{
|
||||
return $bplist->numToBinary($this->value);
|
||||
}
|
||||
}
|
@ -1,106 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* CFPropertyList
|
||||
* {@link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists}
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
* @version $Id$
|
||||
* @example example-read-01.php Read an XML PropertyList
|
||||
* @example example-read-02.php Read a Binary PropertyList
|
||||
* @example example-read-03.php Read a PropertyList without knowing the type
|
||||
* @example example-create-01.php Using the CFPropertyList API
|
||||
* @example example-create-02.php Using {@link CFTypeDetector}
|
||||
* @example example-create-03.php Using {@link CFTypeDetector} with {@link CFDate} and {@link CFData}
|
||||
* @example example-modify-01.php Read, modify and save a PropertyList
|
||||
* LICENSE
|
||||
*
|
||||
* This file is part of CFPropertyList.
|
||||
*
|
||||
* The PHP implementation of Apple's PropertyList can handle XML PropertyLists
|
||||
* as well as binary PropertyLists. It offers functionality to easily convert
|
||||
* data between worlds, e.g. recalculating timestamps from unix epoch to apple
|
||||
* epoch and vice versa. A feature to automagically create (guess) the plist
|
||||
* structure from a normal PHP data structure will help you dump your data to
|
||||
* plist in no time.
|
||||
*
|
||||
* Copyright (c) 2018 Teclib'
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @copyright Copyright © 2018 Teclib
|
||||
* @package plist
|
||||
* @license MIT
|
||||
* @link https://github.com/TECLIB/CFPropertyList/
|
||||
* @link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists
|
||||
*/
|
||||
|
||||
namespace CFPropertyList;
|
||||
use \Iterator, \DOMDocument, \DOMException, DOMImplementation, DOMNode;
|
||||
|
||||
/**
|
||||
* Require IOException, PListException, CFType and CFBinaryPropertyList
|
||||
*/
|
||||
require_once(__DIR__.'/IOException.php');
|
||||
require_once(__DIR__.'/PListException.php');
|
||||
require_once(__DIR__.'/CFType.php');
|
||||
require_once(__DIR__.'/CFBinaryPropertyList.php');
|
||||
require_once(__DIR__.'/CFTypeDetector.php');
|
||||
use Iterator;
|
||||
use DOMDocument;
|
||||
use DOMException;
|
||||
use DOMImplementation;
|
||||
use DOMNode;
|
||||
|
||||
/**
|
||||
* Property List
|
||||
* Interface for handling reading, editing and saving Property Lists as defined by Apple.
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
* @example example-read-01.php Read an XML PropertyList
|
||||
* @example example-read-02.php Read a Binary PropertyList
|
||||
* @example example-read-03.php Read a PropertyList without knowing the type
|
||||
* @example example-create-01.php Using the CFPropertyList API
|
||||
* @example example-create-02.php Using {@link CFTypeDetector}
|
||||
* @example example-create-03.php Using {@link CFTypeDetector} with {@link CFDate} and {@link CFData}
|
||||
* @example example-create-04.php Using and extended {@link CFTypeDetector}
|
||||
* @example example-read-01.php Read an XML PropertyList
|
||||
* @example example-read-02.php Read a Binary PropertyList
|
||||
* @example example-read-03.php Read a PropertyList without knowing the type
|
||||
* @example example-create-01.php Using the CFPropertyList API
|
||||
* @example example-create-02.php Using CFTypeDetector
|
||||
* @example example-create-03.php Using CFTypeDetector with CFDate and CFData
|
||||
* @example example-modify-01.php Read, modify and save a PropertyList
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
class CFPropertyList extends CFBinaryPropertyList implements Iterator
|
||||
{
|
||||
/**
|
||||
* Format constant for binary format
|
||||
* @var integer
|
||||
*/
|
||||
const FORMAT_BINARY = 1;
|
||||
const FORMAT_BINARY = 1;
|
||||
|
||||
/**
|
||||
* Format constant for xml format
|
||||
* @var integer
|
||||
*/
|
||||
const FORMAT_XML = 2;
|
||||
const FORMAT_XML = 2;
|
||||
|
||||
/**
|
||||
* Format constant for automatic format recognizing
|
||||
* @var integer
|
||||
*/
|
||||
const FORMAT_AUTO = 0;
|
||||
const FORMAT_AUTO = 0;
|
||||
|
||||
/**
|
||||
* Path of PropertyList
|
||||
* @var string
|
||||
*/
|
||||
protected $file = null;
|
||||
|
||||
protected $file = null;
|
||||
|
||||
/**
|
||||
* Detected format of PropertyList
|
||||
* @var integer
|
||||
*/
|
||||
protected $detectedFormat = null;
|
||||
protected $detectedFormat = null;
|
||||
|
||||
/**
|
||||
* Path of PropertyList
|
||||
* @var integer
|
||||
*/
|
||||
protected $format = null;
|
||||
protected $format = null;
|
||||
|
||||
/**
|
||||
* CFType nodes
|
||||
* @var array
|
||||
*/
|
||||
protected $value = array();
|
||||
protected $value = array();
|
||||
|
||||
/**
|
||||
* Position of iterator {@link http://php.net/manual/en/class.iterator.php}
|
||||
* @var integer
|
||||
*/
|
||||
protected $iteratorPosition = 0;
|
||||
protected $iteratorPosition = 0;
|
||||
|
||||
/**
|
||||
* List of Keys for numerical iterator access {@link http://php.net/manual/en/class.iterator.php}
|
||||
* @var array
|
||||
*/
|
||||
protected $iteratorKeys = null;
|
||||
protected $iteratorKeys = null;
|
||||
|
||||
/**
|
||||
* List of NodeNames to ClassNames for resolving plist-files
|
||||
* @var array
|
||||
*/
|
||||
protected static $types = array(
|
||||
protected static $types = array(
|
||||
'string' => 'CFString',
|
||||
'real' => 'CFNumber',
|
||||
'integer' => 'CFNumber',
|
||||
@ -110,7 +131,7 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
'data' => 'CFData',
|
||||
'array' => 'CFArray',
|
||||
'dict' => 'CFDictionary'
|
||||
);
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
@ -122,12 +143,15 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @uses $file for storing the current file, if specified
|
||||
* @uses load() for loading the plist-file
|
||||
*/
|
||||
public function __construct($file=null,$format=self::FORMAT_AUTO) {
|
||||
$this->file = $file;
|
||||
$this->format = $format;
|
||||
$this->detectedFormat = $format;
|
||||
if($this->file) $this->load();
|
||||
}
|
||||
public function __construct($file = null, $format = self::FORMAT_AUTO)
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->format = $format;
|
||||
$this->detectedFormat = $format;
|
||||
if ($this->file) {
|
||||
$this->load();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an XML PropertyList.
|
||||
@ -137,9 +161,10 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @throws DOMException if XML-file could not be read properly
|
||||
* @uses load() to actually load the file
|
||||
*/
|
||||
public function loadXML($file=null) {
|
||||
$this->load($file,CFPropertyList::FORMAT_XML);
|
||||
}
|
||||
public function loadXML($file = null)
|
||||
{
|
||||
$this->load($file, CFPropertyList::FORMAT_XML);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an XML PropertyList.
|
||||
@ -148,10 +173,13 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @throws IOException if stream could not be read
|
||||
* @throws DOMException if XML-stream could not be read properly
|
||||
*/
|
||||
public function loadXMLStream($stream) {
|
||||
if(($contents = stream_get_contents($stream)) === FALSE) throw IOException::notReadable('<stream>');
|
||||
$this->parse($contents,CFPropertyList::FORMAT_XML);
|
||||
}
|
||||
public function loadXMLStream($stream)
|
||||
{
|
||||
if (($contents = stream_get_contents($stream)) === false) {
|
||||
throw IOException::notReadable('<stream>');
|
||||
}
|
||||
$this->parse($contents, CFPropertyList::FORMAT_XML);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an binary PropertyList.
|
||||
@ -161,9 +189,10 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @throws PListException if binary plist-file could not be read properly
|
||||
* @uses load() to actually load the file
|
||||
*/
|
||||
public function loadBinary($file=null) {
|
||||
$this->load($file,CFPropertyList::FORMAT_BINARY);
|
||||
}
|
||||
public function loadBinary($file = null)
|
||||
{
|
||||
$this->load($file, CFPropertyList::FORMAT_BINARY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an binary PropertyList.
|
||||
@ -173,10 +202,13 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @throws PListException if binary plist-file could not be read properly
|
||||
* @uses parse() to actually load the file
|
||||
*/
|
||||
public function loadBinaryStream($stream) {
|
||||
if(($contents = stream_get_contents($stream)) === FALSE) throw IOException::notReadable('<stream>');
|
||||
$this->parse($contents,CFPropertyList::FORMAT_BINARY);
|
||||
}
|
||||
public function loadBinaryStream($stream)
|
||||
{
|
||||
if (($contents = stream_get_contents($stream)) === false) {
|
||||
throw IOException::notReadable('<stream>');
|
||||
}
|
||||
$this->parse($contents, CFPropertyList::FORMAT_BINARY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a plist file.
|
||||
@ -191,40 +223,55 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @uses $value reset to empty array
|
||||
* @uses import() for importing the values
|
||||
*/
|
||||
public function load($file=null,$format=null) {
|
||||
$file = $file ? $file : $this->file;
|
||||
$format = $format !== null ? $format : $this->format;
|
||||
$this->value = array();
|
||||
public function load($file = null, $format = null)
|
||||
{
|
||||
$file = $file ? $file : $this->file;
|
||||
$format = $format !== null ? $format : $this->format;
|
||||
$this->value = array();
|
||||
|
||||
if(!is_readable($file)) throw IOException::notReadable($file);
|
||||
|
||||
switch($format) {
|
||||
case CFPropertyList::FORMAT_BINARY:
|
||||
$this->readBinary($file);
|
||||
break;
|
||||
case CFPropertyList::FORMAT_AUTO: // what we now do is ugly, but neccessary to recognize the file format
|
||||
$fd = fopen($file,"rb");
|
||||
if(($magic_number = fread($fd,8)) === false) throw IOException::notReadable($file);
|
||||
fclose($fd);
|
||||
|
||||
$filetype = substr($magic_number,0,6);
|
||||
$version = substr($magic_number,-2);
|
||||
|
||||
if($filetype == "bplist") {
|
||||
if($version != "00") throw new PListException("Wrong file format version! Expected 00, got $version!");
|
||||
$this->detectedFormat = CFPropertyList::FORMAT_BINARY;
|
||||
$this->readBinary($file);
|
||||
break;
|
||||
if (!is_readable($file)) {
|
||||
throw IOException::notReadable($file);
|
||||
}
|
||||
|
||||
switch ($format) {
|
||||
case CFPropertyList::FORMAT_BINARY:
|
||||
$this->readBinary($file);
|
||||
break;
|
||||
case CFPropertyList::FORMAT_AUTO: // what we now do is ugly, but neccessary to recognize the file format
|
||||
$fd = fopen($file, "rb");
|
||||
if (($magic_number = fread($fd, 8)) === false) {
|
||||
throw IOException::notReadable($file);
|
||||
}
|
||||
fclose($fd);
|
||||
|
||||
$filetype = substr($magic_number, 0, 6);
|
||||
$version = substr($magic_number, -2);
|
||||
|
||||
if ($filetype == "bplist") {
|
||||
if ($version != "00") {
|
||||
throw new PListException("Wrong file format version! Expected 00, got $version!");
|
||||
}
|
||||
$this->detectedFormat = CFPropertyList::FORMAT_BINARY;
|
||||
$this->readBinary($file);
|
||||
break;
|
||||
}
|
||||
$this->detectedFormat = CFPropertyList::FORMAT_XML;
|
||||
// else: xml format, break not neccessary
|
||||
case CFPropertyList::FORMAT_XML:
|
||||
$doc = new DOMDocument();
|
||||
$prevXmlErrors = libxml_use_internal_errors(true);
|
||||
libxml_clear_errors();
|
||||
if (!$doc->load($file)) {
|
||||
$message = $this->getLibxmlErrors();
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($prevXmlErrors);
|
||||
throw new DOMException($message);
|
||||
}
|
||||
libxml_use_internal_errors($prevXmlErrors);
|
||||
$this->import($doc->documentElement, $this);
|
||||
break;
|
||||
}
|
||||
$this->detectedFormat = CFPropertyList::FORMAT_XML;
|
||||
// else: xml format, break not neccessary
|
||||
case CFPropertyList::FORMAT_XML:
|
||||
$doc = new DOMDocument();
|
||||
if(!$doc->load($file)) throw new DOMException();
|
||||
$this->import($doc->documentElement, $this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a plist string.
|
||||
@ -239,36 +286,59 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @uses $value reset to empty array
|
||||
* @uses import() for importing the values
|
||||
*/
|
||||
public function parse($str=NULL,$format=NULL) {
|
||||
$format = $format !== null ? $format : $this->format;
|
||||
$str = $str !== null ? $str : $this->content;
|
||||
$this->value = array();
|
||||
|
||||
switch($format) {
|
||||
case CFPropertyList::FORMAT_BINARY:
|
||||
$this->parseBinary($str);
|
||||
break;
|
||||
case CFPropertyList::FORMAT_AUTO: // what we now do is ugly, but neccessary to recognize the file format
|
||||
if(($magic_number = substr($str,0,8)) === false) throw IOException::notReadable("<string>");
|
||||
|
||||
$filetype = substr($magic_number,0,6);
|
||||
$version = substr($magic_number,-2);
|
||||
|
||||
if($filetype == "bplist") {
|
||||
if($version != "00") throw new PListException("Wrong file format version! Expected 00, got $version!");
|
||||
$this->detectedFormat = CFPropertyList::FORMAT_BINARY;
|
||||
$this->parseBinary($str);
|
||||
break;
|
||||
public function parse($str = null, $format = null)
|
||||
{
|
||||
$format = $format !== null ? $format : $this->format;
|
||||
$str = $str !== null ? $str : $this->content;
|
||||
if ($str === null || strlen($str) === 0) {
|
||||
throw IOException::readError('');
|
||||
}
|
||||
$this->value = array();
|
||||
|
||||
switch ($format) {
|
||||
case CFPropertyList::FORMAT_BINARY:
|
||||
$this->parseBinary($str);
|
||||
break;
|
||||
case CFPropertyList::FORMAT_AUTO: // what we now do is ugly, but neccessary to recognize the file format
|
||||
if (($magic_number = substr($str, 0, 8)) === false) {
|
||||
throw IOException::notReadable("<string>");
|
||||
}
|
||||
|
||||
$filetype = substr($magic_number, 0, 6);
|
||||
$version = substr($magic_number, -2);
|
||||
|
||||
if ($filetype == "bplist") {
|
||||
if ($version != "00") {
|
||||
throw new PListException("Wrong file format version! Expected 00, got $version!");
|
||||
}
|
||||
$this->detectedFormat = CFPropertyList::FORMAT_BINARY;
|
||||
$this->parseBinary($str);
|
||||
break;
|
||||
}
|
||||
$this->detectedFormat = CFPropertyList::FORMAT_XML;
|
||||
// else: xml format, break not neccessary
|
||||
case CFPropertyList::FORMAT_XML:
|
||||
$doc = new DOMDocument();
|
||||
$prevXmlErrors = libxml_use_internal_errors(true);
|
||||
libxml_clear_errors();
|
||||
if (!$doc->loadXML($str)) {
|
||||
$message = $this->getLibxmlErrors();
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($prevXmlErrors);
|
||||
throw new DOMException($message);
|
||||
}
|
||||
libxml_use_internal_errors($prevXmlErrors);
|
||||
$this->import($doc->documentElement, $this);
|
||||
break;
|
||||
}
|
||||
$this->detectedFormat = CFPropertyList::FORMAT_XML;
|
||||
// else: xml format, break not neccessary
|
||||
case CFPropertyList::FORMAT_XML:
|
||||
$doc = new DOMDocument();
|
||||
if(!$doc->loadXML($str)) throw new DOMException();
|
||||
$this->import($doc->documentElement, $this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getLibxmlErrors()
|
||||
{
|
||||
return implode(', ', array_map(function (\LibXMLError $error) {
|
||||
return trim("{$error->line}:{$error->column} [$error->code] $error->message");
|
||||
}, libxml_get_errors()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a DOMNode into a CFType.
|
||||
@ -276,77 +346,91 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @param CFDictionary|CFArray|CFPropertyList $parent
|
||||
* @return void
|
||||
*/
|
||||
protected function import(DOMNode $node, $parent) {
|
||||
// abort if there are no children
|
||||
if(!$node->childNodes->length) return;
|
||||
protected function import(DOMNode $node, $parent)
|
||||
{
|
||||
// abort if there are no children
|
||||
if (!$node->childNodes->length) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($node->childNodes as $n) {
|
||||
// skip if we can't handle the element
|
||||
if(!isset(self::$types[$n->nodeName])) continue;
|
||||
|
||||
$class = 'CFPropertyList\\'.self::$types[$n->nodeName];
|
||||
$key = null;
|
||||
|
||||
// find previous <key> if possible
|
||||
$ps = $n->previousSibling;
|
||||
while($ps && $ps->nodeName == '#text' && $ps->previousSibling) $ps = $ps->previousSibling;
|
||||
|
||||
// read <key> if possible
|
||||
if($ps && $ps->nodeName == 'key') $key = $ps->firstChild->nodeValue;
|
||||
|
||||
switch($n->nodeName) {
|
||||
case 'date':
|
||||
$value = new $class(CFDate::dateValue($n->nodeValue));
|
||||
break;
|
||||
case 'data':
|
||||
$value = new $class($n->nodeValue,true);
|
||||
break;
|
||||
case 'string':
|
||||
$value = new $class($n->nodeValue);
|
||||
break;
|
||||
|
||||
case 'real':
|
||||
case 'integer':
|
||||
$value = new $class($n->nodeName == 'real' ? floatval($n->nodeValue) : intval($n->nodeValue));
|
||||
break;
|
||||
|
||||
case 'true':
|
||||
case 'false':
|
||||
$value = new $class($n->nodeName == 'true');
|
||||
break;
|
||||
|
||||
case 'array':
|
||||
case 'dict':
|
||||
$value = new $class();
|
||||
$this->import($n, $value);
|
||||
|
||||
if($value instanceof CFDictionary) {
|
||||
$hsh = $value->getValue();
|
||||
if(isset($hsh['CF$UID']) && count($hsh) == 1) {
|
||||
$value = new CFUid($hsh['CF$UID']->getValue());
|
||||
foreach ($node->childNodes as $n) {
|
||||
// skip if we can't handle the element
|
||||
if (!isset(self::$types[$n->nodeName])) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
$class = __NAMESPACE__ . '\\'.self::$types[$n->nodeName];
|
||||
$key = null;
|
||||
|
||||
// Dictionaries need a key
|
||||
if($parent instanceof CFDictionary) $parent->add($key, $value);
|
||||
// others don't
|
||||
else $parent->add($value);
|
||||
// find previous <key> if possible
|
||||
$ps = $n->previousSibling;
|
||||
while ($ps && $ps->nodeName == '#text' && $ps->previousSibling) {
|
||||
$ps = $ps->previousSibling;
|
||||
}
|
||||
|
||||
// read <key> if possible
|
||||
if ($ps && $ps->nodeName == 'key') {
|
||||
$key = $ps->firstChild->nodeValue;
|
||||
}
|
||||
|
||||
switch ($n->nodeName) {
|
||||
case 'date':
|
||||
$value = new $class(CFDate::dateValue($n->nodeValue));
|
||||
break;
|
||||
case 'data':
|
||||
$value = new $class($n->nodeValue, true);
|
||||
break;
|
||||
case 'string':
|
||||
$value = new $class($n->nodeValue);
|
||||
break;
|
||||
|
||||
case 'real':
|
||||
case 'integer':
|
||||
$value = new $class($n->nodeName == 'real' ? floatval($n->nodeValue) : intval($n->nodeValue));
|
||||
break;
|
||||
|
||||
case 'true':
|
||||
case 'false':
|
||||
$value = new $class($n->nodeName == 'true');
|
||||
break;
|
||||
|
||||
case 'array':
|
||||
case 'dict':
|
||||
$value = new $class();
|
||||
$this->import($n, $value);
|
||||
|
||||
if ($value instanceof CFDictionary) {
|
||||
$hsh = $value->getValue();
|
||||
if (isset($hsh['CF$UID']) && count($hsh) == 1) {
|
||||
$value = new CFUid($hsh['CF$UID']->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ($parent instanceof CFDictionary) {
|
||||
// Dictionaries need a key
|
||||
$parent->add($key, $value);
|
||||
} else {
|
||||
// others don't
|
||||
$parent->add($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert CFPropertyList to XML and save to file.
|
||||
* @param string $file Path of PropertyList, defaults to {@link $file}
|
||||
* @param bool $formatted Print plist formatted (i.e. with newlines and whitespace indention) if true; defaults to false
|
||||
* @return void
|
||||
* @throws IOException if file could not be read
|
||||
* @uses $file if $file was not specified
|
||||
*/
|
||||
public function saveXML($file) {
|
||||
$this->save($file,CFPropertyList::FORMAT_XML);
|
||||
}
|
||||
public function saveXML($file, $formatted = false)
|
||||
{
|
||||
$this->save($file, CFPropertyList::FORMAT_XML, $formatted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert CFPropertyList to binary format (bplist00) and save to file.
|
||||
@ -355,69 +439,79 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @throws IOException if file could not be read
|
||||
* @uses $file if $file was not specified
|
||||
*/
|
||||
public function saveBinary($file) {
|
||||
$this->save($file,CFPropertyList::FORMAT_BINARY);
|
||||
}
|
||||
public function saveBinary($file)
|
||||
{
|
||||
$this->save($file, CFPropertyList::FORMAT_BINARY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert CFPropertyList to XML or binary and save to file.
|
||||
* @param string $file Path of PropertyList, defaults to {@link $file}
|
||||
* @param string $format Format of PropertyList, defaults to {@link $format}
|
||||
* @param bool $formatted_xml Print XML plist formatted (i.e. with newlines and whitespace indention) if true; defaults to false
|
||||
* @return void
|
||||
* @throws IOException if file could not be read
|
||||
* @throws PListException if evaluated $format is neither {@link FORMAT_XML} nor {@link FORMAL_BINARY}
|
||||
* @uses $file if $file was not specified
|
||||
* @uses $format if $format was not specified
|
||||
*/
|
||||
public function save($file=null,$format=null) {
|
||||
$file = $file ? $file : $this->file;
|
||||
$format = $format ? $format : $this->format;
|
||||
if($format == self::FORMAT_AUTO)$format = $this->detectedFormat;
|
||||
public function save($file = null, $format = null, $formatted_xml = false)
|
||||
{
|
||||
$file = $file ? $file : $this->file;
|
||||
$format = $format ? $format : $this->format;
|
||||
if ($format == self::FORMAT_AUTO) {
|
||||
$format = $this->detectedFormat;
|
||||
}
|
||||
|
||||
if( !in_array( $format, array( self::FORMAT_BINARY, self::FORMAT_XML ) ) )
|
||||
throw new PListException( "format {$format} is not supported, use CFPropertyList::FORMAT_BINARY or CFPropertyList::FORMAT_XML" );
|
||||
if (!in_array($format, array( self::FORMAT_BINARY, self::FORMAT_XML ))) {
|
||||
throw new PListException("format {$format} is not supported, use CFPropertyList::FORMAT_BINARY or CFPropertyList::FORMAT_XML");
|
||||
}
|
||||
|
||||
if(!file_exists($file)) {
|
||||
// dirname("file.xml") == "" and is treated as the current working directory
|
||||
if(!is_writable(dirname($file))) throw IOException::notWritable($file);
|
||||
if (!file_exists($file)) {
|
||||
// dirname("file.xml") == "" and is treated as the current working directory
|
||||
if (!is_writable(dirname($file))) {
|
||||
throw IOException::notWritable($file);
|
||||
}
|
||||
} elseif (!is_writable($file)) {
|
||||
throw IOException::notWritable($file);
|
||||
}
|
||||
|
||||
$content = $format == self::FORMAT_BINARY ? $this->toBinary() : $this->toXML($formatted_xml);
|
||||
|
||||
$fh = fopen($file, 'wb');
|
||||
fwrite($fh, $content);
|
||||
fclose($fh);
|
||||
}
|
||||
else if(!is_writable($file)) throw IOException::notWritable($file);
|
||||
|
||||
$content = $format == self::FORMAT_BINARY ? $this->toBinary() : $this->toXML();
|
||||
|
||||
$fh = fopen($file, 'wb');
|
||||
fwrite($fh,$content);
|
||||
fclose($fh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert CFPropertyList to XML
|
||||
* @param bool $formatted Print plist formatted (i.e. with newlines and whitespace indention) if true; defaults to false
|
||||
* @return string The XML content
|
||||
*/
|
||||
public function toXML($formatted=false) {
|
||||
$domimpl = new DOMImplementation();
|
||||
// <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
$dtd = $domimpl->createDocumentType('plist', '-//Apple//DTD PLIST 1.0//EN', 'http://www.apple.com/DTDs/PropertyList-1.0.dtd');
|
||||
$doc = $domimpl->createDocument(null, "plist", $dtd);
|
||||
$doc->encoding = "UTF-8";
|
||||
public function toXML($formatted = false)
|
||||
{
|
||||
$domimpl = new DOMImplementation();
|
||||
// <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
$dtd = $domimpl->createDocumentType('plist', '-//Apple//DTD PLIST 1.0//EN', 'http://www.apple.com/DTDs/PropertyList-1.0.dtd');
|
||||
$doc = $domimpl->createDocument(null, "plist", $dtd);
|
||||
$doc->encoding = "UTF-8";
|
||||
|
||||
// format output
|
||||
if($formatted) {
|
||||
$doc->formatOutput = true;
|
||||
$doc->preserveWhiteSpace = true;
|
||||
// format output
|
||||
if ($formatted) {
|
||||
$doc->formatOutput = true;
|
||||
$doc->preserveWhiteSpace = true;
|
||||
}
|
||||
|
||||
// get documentElement and set attribs
|
||||
$plist = $doc->documentElement;
|
||||
$plist->setAttribute('version', '1.0');
|
||||
|
||||
// add PropertyList's children
|
||||
$plist->appendChild($this->getValue(true)->toXML($doc));
|
||||
|
||||
return $doc->saveXML();
|
||||
}
|
||||
|
||||
// get documentElement and set attribs
|
||||
$plist = $doc->documentElement;
|
||||
$plist->setAttribute('version', '1.0');
|
||||
|
||||
// add PropertyList's children
|
||||
$plist->appendChild($this->getValue(true)->toXML($doc));
|
||||
|
||||
return $doc->saveXML();
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* M A N I P U L A T I O N
|
||||
@ -429,13 +523,15 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @return void
|
||||
* @uses $value for adding $value
|
||||
*/
|
||||
public function add(CFType $value=null) {
|
||||
// anything but CFType is null, null is an empty string - sad but true
|
||||
if( !$value )
|
||||
$value = new CFString();
|
||||
public function add(CFType $value = null)
|
||||
{
|
||||
// anything but CFType is null, null is an empty string - sad but true
|
||||
if (!$value) {
|
||||
$value = new CFString();
|
||||
}
|
||||
|
||||
$this->value[] = $value;
|
||||
}
|
||||
$this->value[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CFType from collection.
|
||||
@ -443,10 +539,13 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @return CFType CFType found at $key, null else
|
||||
* @uses $value for retrieving CFType of $key
|
||||
*/
|
||||
public function get($key) {
|
||||
if(isset($this->value[$key])) return $this->value[$key];
|
||||
return null;
|
||||
}
|
||||
public function get($key)
|
||||
{
|
||||
if (isset($this->value[$key])) {
|
||||
return $this->value[$key];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic getter (magic)
|
||||
@ -456,9 +555,10 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @author Sean Coates <sean@php.net>
|
||||
* @link http://php.net/oop5.overloading
|
||||
*/
|
||||
public function __get($key) {
|
||||
return $this->get($key);
|
||||
}
|
||||
public function __get($key)
|
||||
{
|
||||
return $this->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove CFType from collection.
|
||||
@ -466,26 +566,28 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @return CFType removed CFType, null else
|
||||
* @uses $value for removing CFType of $key
|
||||
*/
|
||||
public function del($key) {
|
||||
if(isset($this->value[$key])) {
|
||||
$t = $this->value[$key];
|
||||
unset($this->value[$key]);
|
||||
return $t;
|
||||
}
|
||||
public function del($key)
|
||||
{
|
||||
if (isset($this->value[$key])) {
|
||||
$t = $this->value[$key];
|
||||
unset($this->value[$key]);
|
||||
return $t;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty the collection
|
||||
* @return array the removed CFTypes
|
||||
* @uses $value for removing CFType of $key
|
||||
*/
|
||||
public function purge() {
|
||||
$t = $this->value;
|
||||
$this->value = array();
|
||||
return $t;
|
||||
}
|
||||
public function purge()
|
||||
{
|
||||
$t = $this->value;
|
||||
$this->value = array();
|
||||
return $t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get first (and only) child, or complete collection.
|
||||
@ -493,20 +595,23 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @return CFType|array CFType or list of CFTypes known to the PropertyList
|
||||
* @uses $value for retrieving CFTypes
|
||||
*/
|
||||
public function getValue($cftype=false) {
|
||||
if(count($this->value) === 1) {
|
||||
$t = array_values( $this->value );
|
||||
return $t[0];
|
||||
}
|
||||
if($cftype) {
|
||||
$t = new CFArray();
|
||||
foreach( $this->value as $value ) {
|
||||
if( $value instanceof CFType ) $t->add($value);
|
||||
}
|
||||
return $t;
|
||||
public function getValue($cftype = false)
|
||||
{
|
||||
if (count($this->value) === 1) {
|
||||
$t = array_values($this->value);
|
||||
return $t[0];
|
||||
}
|
||||
if ($cftype) {
|
||||
$t = new CFArray();
|
||||
foreach ($this->value as $value) {
|
||||
if ($value instanceof CFType) {
|
||||
$t->add($value);
|
||||
}
|
||||
}
|
||||
return $t;
|
||||
}
|
||||
return $this->value;
|
||||
}
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create CFType-structure from guessing the data-types.
|
||||
@ -517,13 +622,15 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @uses CFTypeDetector for actual type detection
|
||||
* @deprecated
|
||||
*/
|
||||
public static function guess($value, $options=array()) {
|
||||
static $t = null;
|
||||
if( $t === null )
|
||||
$t = new CFTypeDetector( $options );
|
||||
public static function guess($value, $options = array())
|
||||
{
|
||||
static $t = null;
|
||||
if ($t === null) {
|
||||
$t = new CFTypeDetector($options);
|
||||
}
|
||||
|
||||
return $t->toCFType( $value );
|
||||
}
|
||||
return $t->toCFType($value);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
@ -535,13 +642,18 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @return mixed primitive value of first (and only) CFType, or array of primitive values of collection
|
||||
* @uses $value for retrieving CFTypes
|
||||
*/
|
||||
public function toArray() {
|
||||
$a = array();
|
||||
foreach($this->value as $value) $a[] = $value->toArray();
|
||||
if(count($a) === 1) return $a[0];
|
||||
public function toArray()
|
||||
{
|
||||
$a = array();
|
||||
foreach ($this->value as $value) {
|
||||
$a[] = $value->toArray();
|
||||
}
|
||||
if (count($a) === 1) {
|
||||
return $a[0];
|
||||
}
|
||||
|
||||
return $a;
|
||||
}
|
||||
return $a;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
@ -555,10 +667,11 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @uses $iteratorPosition set to 0
|
||||
* @uses $iteratorKeys store keys of {@link $value}
|
||||
*/
|
||||
public function rewind() {
|
||||
$this->iteratorPosition = 0;
|
||||
$this->iteratorKeys = array_keys($this->value);
|
||||
}
|
||||
public function rewind()
|
||||
{
|
||||
$this->iteratorPosition = 0;
|
||||
$this->iteratorKeys = array_keys($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Iterator's current {@link CFType} identified by {@link $iteratorPosition}
|
||||
@ -567,9 +680,10 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @uses $iteratorPosition identify current key
|
||||
* @uses $iteratorKeys identify current value
|
||||
*/
|
||||
public function current() {
|
||||
return $this->value[$this->iteratorKeys[$this->iteratorPosition]];
|
||||
}
|
||||
public function current()
|
||||
{
|
||||
return $this->value[$this->iteratorKeys[$this->iteratorPosition]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Iterator's current key identified by {@link $iteratorPosition}
|
||||
@ -578,9 +692,10 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @uses $iteratorPosition identify current key
|
||||
* @uses $iteratorKeys identify current value
|
||||
*/
|
||||
public function key() {
|
||||
return $this->iteratorKeys[$this->iteratorPosition];
|
||||
}
|
||||
public function key()
|
||||
{
|
||||
return $this->iteratorKeys[$this->iteratorPosition];
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment {@link $iteratorPosition} to address next {@see CFType}
|
||||
@ -588,9 +703,10 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @return void
|
||||
* @uses $iteratorPosition increment by 1
|
||||
*/
|
||||
public function next() {
|
||||
$this->iteratorPosition++;
|
||||
}
|
||||
public function next()
|
||||
{
|
||||
$this->iteratorPosition++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if {@link $iteratorPosition} addresses a valid element of {@link $value}
|
||||
@ -599,10 +715,10 @@ class CFPropertyList extends CFBinaryPropertyList implements Iterator {
|
||||
* @uses $iteratorPosition test if within {@link $iteratorKeys}
|
||||
* @uses $iteratorPosition test if within {@link $value}
|
||||
*/
|
||||
public function valid() {
|
||||
return isset($this->iteratorKeys[$this->iteratorPosition]) && isset($this->value[$this->iteratorKeys[$this->iteratorPosition]]);
|
||||
}
|
||||
|
||||
public function valid()
|
||||
{
|
||||
return isset($this->iteratorKeys[$this->iteratorPosition]) && isset($this->value[$this->iteratorKeys[$this->iteratorPosition]]);
|
||||
}
|
||||
}
|
||||
|
||||
# eof
|
||||
|
76
lib/plist/classes/CFPropertyList/CFString.php
Normal file
76
lib/plist/classes/CFPropertyList/CFString.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* LICENSE
|
||||
*
|
||||
* This file is part of CFPropertyList.
|
||||
*
|
||||
* The PHP implementation of Apple's PropertyList can handle XML PropertyLists
|
||||
* as well as binary PropertyLists. It offers functionality to easily convert
|
||||
* data between worlds, e.g. recalculating timestamps from unix epoch to apple
|
||||
* epoch and vice versa. A feature to automagically create (guess) the plist
|
||||
* structure from a normal PHP data structure will help you dump your data to
|
||||
* plist in no time.
|
||||
*
|
||||
* Copyright (c) 2018 Teclib'
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @copyright Copyright © 2018 Teclib
|
||||
* @package plist
|
||||
* @license MIT
|
||||
* @link https://github.com/TECLIB/CFPropertyList/
|
||||
* @link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace CFPropertyList;
|
||||
|
||||
use \DOMDocument;
|
||||
use \Iterator;
|
||||
use \ArrayAccess;
|
||||
|
||||
/**
|
||||
* String Type for CFPropertyList as defined by Apple.
|
||||
*/
|
||||
class CFString extends CFType
|
||||
{
|
||||
/**
|
||||
* Get XML-Node.
|
||||
* @param DOMDocument $doc DOMDocument to create DOMNode in
|
||||
* @param string $nodeName For compatibility reasons; just ignore it
|
||||
* @return DOMNode <string>-Element
|
||||
*/
|
||||
public function toXML(DOMDocument $doc, $nodeName = "")
|
||||
{
|
||||
return parent::toXML($doc, 'string');
|
||||
}
|
||||
|
||||
/**
|
||||
* convert value to binary representation
|
||||
* @param CFBinaryPropertyList The binary property list object
|
||||
* @return The offset in the object table
|
||||
*/
|
||||
public function toBinary(CFBinaryPropertyList &$bplist)
|
||||
{
|
||||
return $bplist->stringToBinary($this->value);
|
||||
}
|
||||
}
|
@ -1,41 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* Data-Types for CFPropertyList as defined by Apple.
|
||||
* {@link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists}
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
* @subpackage plist.types
|
||||
* @version $Id$
|
||||
* LICENSE
|
||||
*
|
||||
* This file is part of CFPropertyList.
|
||||
*
|
||||
* The PHP implementation of Apple's PropertyList can handle XML PropertyLists
|
||||
* as well as binary PropertyLists. It offers functionality to easily convert
|
||||
* data between worlds, e.g. recalculating timestamps from unix epoch to apple
|
||||
* epoch and vice versa. A feature to automagically create (guess) the plist
|
||||
* structure from a normal PHP data structure will help you dump your data to
|
||||
* plist in no time.
|
||||
*
|
||||
* Copyright (c) 2018 Teclib'
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @copyright Copyright © 2018 Teclib
|
||||
* @package plist
|
||||
* @license MIT
|
||||
* @link https://github.com/TECLIB/CFPropertyList/
|
||||
* @link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace CFPropertyList;
|
||||
use \DOMDocument, \Iterator, \ArrayAccess;
|
||||
|
||||
use \DOMDocument;
|
||||
use \Iterator;
|
||||
use \ArrayAccess;
|
||||
|
||||
/**
|
||||
* Base-Class of all CFTypes used by CFPropertyList
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
* @subpackage plist.types
|
||||
* @version $Id$
|
||||
*Base-Class of all CFTypes used by CFPropertyList.
|
||||
* @example example-create-01.php Using the CFPropertyList API
|
||||
* @example example-create-02.php Using CFPropertyList::guess()
|
||||
* @example example-create-03.php Using CFPropertyList::guess() with {@link CFDate} and {@link CFData}
|
||||
*/
|
||||
abstract class CFType {
|
||||
abstract class CFType
|
||||
{
|
||||
/**
|
||||
* CFType nodes
|
||||
* @var array
|
||||
*/
|
||||
protected $value = null;
|
||||
protected $value = null;
|
||||
|
||||
/**
|
||||
* Create new CFType.
|
||||
* @param mixed $value Value of CFType
|
||||
*/
|
||||
public function __construct($value=null) {
|
||||
$this->setValue($value);
|
||||
}
|
||||
public function __construct($value = null)
|
||||
{
|
||||
$this->setValue($value);
|
||||
}
|
||||
|
||||
/************************************************************************************************
|
||||
* M A G I C P R O P E R T I E S
|
||||
@ -45,17 +79,19 @@ abstract class CFType {
|
||||
* Get the CFType's value
|
||||
* @return mixed CFType's value
|
||||
*/
|
||||
public function getValue() {
|
||||
return $this->value;
|
||||
}
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CFType's value
|
||||
* @return void
|
||||
*/
|
||||
public function setValue($value) {
|
||||
$this->value = $value;
|
||||
}
|
||||
public function setValue($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/************************************************************************************************
|
||||
* S E R I A L I Z I N G
|
||||
@ -68,690 +104,30 @@ abstract class CFType {
|
||||
* @return DOMNode Node created based on CType
|
||||
* @uses $value as nodeValue
|
||||
*/
|
||||
public function toXML(DOMDocument $doc, $nodeName) {
|
||||
$node = $doc->createElement($nodeName);
|
||||
$text = $doc->createTextNode($this->value);
|
||||
$node->appendChild($text);
|
||||
return $node;
|
||||
}
|
||||
public function toXML(DOMDocument $doc, $nodeName = "")
|
||||
{
|
||||
$node = $doc->createElement($nodeName);
|
||||
$text = $doc->createTextNode($this->value);
|
||||
$node->appendChild($text);
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert value to binary representation
|
||||
* @param CFBinaryPropertyList The binary property list object
|
||||
* @return The offset in the object table
|
||||
*/
|
||||
public abstract function toBinary(CFBinaryPropertyList &$bplist);
|
||||
abstract public function toBinary(CFBinaryPropertyList &$bplist);
|
||||
|
||||
/**
|
||||
* Get CFType's value.
|
||||
* @return mixed primitive value
|
||||
* @uses $value for retrieving primitive of CFType
|
||||
*/
|
||||
public function toArray() {
|
||||
return $this->getValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* String Type of CFPropertyList
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
* @subpackage plist.types
|
||||
*/
|
||||
class CFString extends CFType {
|
||||
/**
|
||||
* Get XML-Node.
|
||||
* @param DOMDocument $doc DOMDocument to create DOMNode in
|
||||
* @param string $nodeName For compatibility reasons; just ignore it
|
||||
* @return DOMNode <string>-Element
|
||||
*/
|
||||
public function toXML(DOMDocument $doc,$nodeName="") {
|
||||
return parent::toXML($doc, 'string');
|
||||
}
|
||||
|
||||
/**
|
||||
* convert value to binary representation
|
||||
* @param CFBinaryPropertyList The binary property list object
|
||||
* @return The offset in the object table
|
||||
*/
|
||||
public function toBinary(CFBinaryPropertyList &$bplist) {
|
||||
return $bplist->stringToBinary($this->value);
|
||||
}
|
||||
}
|
||||
|
||||
class CFUid extends CFType {
|
||||
public
|
||||
function toXML(DOMDocument $doc,$nodeName="") {
|
||||
$obj = new CFDictionary(array('CF$UID' => new CFNumber($this->value)));
|
||||
return $obj->toXml($doc);
|
||||
}
|
||||
|
||||
public
|
||||
function toBinary(CFBinaryPropertyList &$bplist) {
|
||||
return $bplist->uidToBinary($this->value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Number Type of CFPropertyList
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
* @subpackage plist.types
|
||||
*/
|
||||
class CFNumber extends CFType {
|
||||
/**
|
||||
* Get XML-Node.
|
||||
* Returns <real> if $value is a float, <integer> if $value is an integer.
|
||||
* @param DOMDocument $doc DOMDocument to create DOMNode in
|
||||
* @param string $nodeName For compatibility reasons; just ignore it
|
||||
* @return DOMNode <real> or <integer>-Element
|
||||
*/
|
||||
public function toXML(DOMDocument $doc,$nodeName="") {
|
||||
$ret = 'real';
|
||||
if(intval($this->value) == $this->value && !is_float($this->value) && strpos($this->value,'.') === false) {
|
||||
$this->value = intval($this->value);
|
||||
$ret = 'integer';
|
||||
public function toArray()
|
||||
{
|
||||
return $this->getValue();
|
||||
}
|
||||
return parent::toXML($doc, $ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* convert value to binary representation
|
||||
* @param CFBinaryPropertyList The binary property list object
|
||||
* @return The offset in the object table
|
||||
*/
|
||||
public function toBinary(CFBinaryPropertyList &$bplist) {
|
||||
return $bplist->numToBinary($this->value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Date Type of CFPropertyList
|
||||
* Note: CFDate uses Unix timestamp (epoch) to store dates internally
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
* @subpackage plist.types
|
||||
*/
|
||||
class CFDate extends CFType {
|
||||
const TIMESTAMP_APPLE = 0;
|
||||
const TIMESTAMP_UNIX = 1;
|
||||
const DATE_DIFF_APPLE_UNIX = 978307200;
|
||||
|
||||
/**
|
||||
* Create new Date CFType.
|
||||
* @param integer $value timestamp to set
|
||||
* @param integer $format format the timestamp is specified in, use {@link TIMESTAMP_APPLE} or {@link TIMESTAMP_UNIX}, defaults to {@link TIMESTAMP_APPLE}
|
||||
* @uses setValue() to convert the timestamp
|
||||
*/
|
||||
function __construct($value,$format=CFDate::TIMESTAMP_UNIX) {
|
||||
$this->setValue($value,$format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Date CFType's value.
|
||||
* @param integer $value timestamp to set
|
||||
* @param integer $format format the timestamp is specified in, use {@link TIMESTAMP_APPLE} or {@link TIMESTAMP_UNIX}, defaults to {@link TIMESTAMP_UNIX}
|
||||
* @return void
|
||||
* @uses TIMESTAMP_APPLE to determine timestamp type
|
||||
* @uses TIMESTAMP_UNIX to determine timestamp type
|
||||
* @uses DATE_DIFF_APPLE_UNIX to convert Apple-timestamp to Unix-timestamp
|
||||
*/
|
||||
function setValue($value,$format=CFDate::TIMESTAMP_UNIX) {
|
||||
if($format == CFDate::TIMESTAMP_UNIX) $this->value = $value;
|
||||
else $this->value = $value + CFDate::DATE_DIFF_APPLE_UNIX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Date CFType's value.
|
||||
* @param integer $format format the timestamp is specified in, use {@link TIMESTAMP_APPLE} or {@link TIMESTAMP_UNIX}, defaults to {@link TIMESTAMP_UNIX}
|
||||
* @return integer Unix timestamp
|
||||
* @uses TIMESTAMP_APPLE to determine timestamp type
|
||||
* @uses TIMESTAMP_UNIX to determine timestamp type
|
||||
* @uses DATE_DIFF_APPLE_UNIX to convert Unix-timestamp to Apple-timestamp
|
||||
*/
|
||||
function getValue($format=CFDate::TIMESTAMP_UNIX) {
|
||||
if($format == CFDate::TIMESTAMP_UNIX) return $this->value;
|
||||
else return $this->value - CFDate::DATE_DIFF_APPLE_UNIX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get XML-Node.
|
||||
* @param DOMDocument $doc DOMDocument to create DOMNode in
|
||||
* @param string $nodeName For compatibility reasons; just ignore it
|
||||
* @return DOMNode <date>-Element
|
||||
*/
|
||||
public function toXML(DOMDocument $doc,$nodeName="") {
|
||||
$text = $doc->createTextNode(gmdate("Y-m-d\TH:i:s\Z",$this->getValue()));
|
||||
$node = $doc->createElement("date");
|
||||
$node->appendChild($text);
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert value to binary representation
|
||||
* @param CFBinaryPropertyList The binary property list object
|
||||
* @return The offset in the object table
|
||||
*/
|
||||
public function toBinary(CFBinaryPropertyList &$bplist) {
|
||||
return $bplist->dateToBinary($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a UNIX timestamp from a PList date string
|
||||
* @param string $val The date string (e.g. "2009-05-13T20:23:43Z")
|
||||
* @return integer The UNIX timestamp
|
||||
* @throws PListException when encountering an unknown date string format
|
||||
*/
|
||||
public static function dateValue($val) {
|
||||
//2009-05-13T20:23:43Z
|
||||
if(!preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/',$val,$matches)) throw new PListException("Unknown date format: $val");
|
||||
return gmmktime($matches[4],$matches[5],$matches[6],$matches[2],$matches[3],$matches[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Boolean Type of CFPropertyList
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
* @subpackage plist.types
|
||||
*/
|
||||
class CFBoolean extends CFType {
|
||||
/**
|
||||
* Get XML-Node.
|
||||
* Returns <true> if $value is a true, <false> if $value is false.
|
||||
* @param DOMDocument $doc DOMDocument to create DOMNode in
|
||||
* @param string $nodeName For compatibility reasons; just ignore it
|
||||
* @return DOMNode <true> or <false>-Element
|
||||
*/
|
||||
public function toXML(DOMDocument $doc,$nodeName="") {
|
||||
return $doc->createElement($this->value ? 'true' : 'false');
|
||||
}
|
||||
|
||||
/**
|
||||
* convert value to binary representation
|
||||
* @param CFBinaryPropertyList The binary property list object
|
||||
* @return The offset in the object table
|
||||
*/
|
||||
public function toBinary(CFBinaryPropertyList &$bplist) {
|
||||
return $bplist->boolToBinary($this->value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Data Type of CFPropertyList
|
||||
* Note: Binary data is base64-encoded.
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
* @subpackage plist.types
|
||||
*/
|
||||
class CFData extends CFType {
|
||||
/**
|
||||
* Create new Data CFType
|
||||
* @param string $value data to be contained by new object
|
||||
* @param boolean $already_coded if true $value will not be base64-encoded, defaults to false
|
||||
*/
|
||||
public function __construct($value=null,$already_coded=false) {
|
||||
if($already_coded) $this->value = $value;
|
||||
else $this->setValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CFType's value and base64-encode it.
|
||||
* <b>Note:</b> looks like base64_encode has troubles with UTF-8 encoded strings
|
||||
* @return void
|
||||
*/
|
||||
public function setValue($value) {
|
||||
//if(function_exists('mb_check_encoding') && mb_check_encoding($value, 'UTF-8')) $value = utf8_decode($value);
|
||||
$this->value = base64_encode($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get base64 encoded data
|
||||
* @return string The base64 encoded data value
|
||||
*/
|
||||
public function getCodedValue() {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base64-decoded CFType's value.
|
||||
* @return mixed CFType's value
|
||||
*/
|
||||
public function getValue() {
|
||||
return base64_decode($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get XML-Node.
|
||||
* @param DOMDocument $doc DOMDocument to create DOMNode in
|
||||
* @param string $nodeName For compatibility reasons; just ignore it
|
||||
* @return DOMNode <data>-Element
|
||||
*/
|
||||
public function toXML(DOMDocument $doc,$nodeName="") {
|
||||
return parent::toXML($doc, 'data');
|
||||
}
|
||||
|
||||
/**
|
||||
* convert value to binary representation
|
||||
* @param CFBinaryPropertyList The binary property list object
|
||||
* @return The offset in the object table
|
||||
*/
|
||||
public function toBinary(CFBinaryPropertyList &$bplist) {
|
||||
return $bplist->dataToBinary($this->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Type of CFPropertyList
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
* @subpackage plist.types
|
||||
*/
|
||||
class CFArray extends CFType implements Iterator, ArrayAccess {
|
||||
/**
|
||||
* Position of iterator {@link http://php.net/manual/en/class.iterator.php}
|
||||
* @var integer
|
||||
*/
|
||||
protected $iteratorPosition = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Create new CFType.
|
||||
* @param array $value Value of CFType
|
||||
*/
|
||||
public function __construct($value=array()) {
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CFType's value
|
||||
* <b>Note:</b> this dummy does nothing
|
||||
* @return void
|
||||
*/
|
||||
public function setValue($value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add CFType to collection.
|
||||
* @param CFType $value CFType to add to collection, defaults to null which results in an empty {@link CFString}
|
||||
* @return void
|
||||
* @uses $value for adding $value
|
||||
*/
|
||||
public function add(CFType $value=null) {
|
||||
// anything but CFType is null, null is an empty string - sad but true
|
||||
if( !$value )
|
||||
$value = new CFString();
|
||||
|
||||
$this->value[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CFType from collection.
|
||||
* @param integer $key Key of CFType to retrieve from collection
|
||||
* @return CFType CFType found at $key, null else
|
||||
* @uses $value for retrieving CFType of $key
|
||||
*/
|
||||
public function get($key) {
|
||||
if(isset($this->value[$key])) return $this->value[$key];
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove CFType from collection.
|
||||
* @param integer $key Key of CFType to removes from collection
|
||||
* @return CFType removed CFType, null else
|
||||
* @uses $value for removing CFType of $key
|
||||
*/
|
||||
public function del($key) {
|
||||
if(isset($this->value[$key])) unset($this->value[$key]);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* S E R I A L I Z I N G
|
||||
************************************************************************************************/
|
||||
|
||||
/**
|
||||
* Get XML-Node.
|
||||
* @param DOMDocument $doc DOMDocument to create DOMNode in
|
||||
* @param string $nodeName For compatibility reasons; just ignore it
|
||||
* @return DOMNode <array>-Element
|
||||
*/
|
||||
public function toXML(DOMDocument $doc,$nodeName="") {
|
||||
$node = $doc->createElement('array');
|
||||
|
||||
foreach($this->value as $value) $node->appendChild($value->toXML($doc));
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert value to binary representation
|
||||
* @param CFBinaryPropertyList The binary property list object
|
||||
* @return The offset in the object table
|
||||
*/
|
||||
public function toBinary(CFBinaryPropertyList &$bplist) {
|
||||
return $bplist->arrayToBinary($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CFType's value.
|
||||
* @return array primitive value
|
||||
* @uses $value for retrieving primitive of CFType
|
||||
*/
|
||||
public function toArray() {
|
||||
$a = array();
|
||||
foreach($this->value as $value) $a[] = $value->toArray();
|
||||
return $a;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* I T E R A T O R I N T E R F A C E
|
||||
************************************************************************************************/
|
||||
|
||||
/**
|
||||
* Rewind {@link $iteratorPosition} to first position (being 0)
|
||||
* @link http://php.net/manual/en/iterator.rewind.php
|
||||
* @return void
|
||||
* @uses $iteratorPosition set to 0
|
||||
*/
|
||||
public function rewind() {
|
||||
$this->iteratorPosition = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Iterator's current {@link CFType} identified by {@link $iteratorPosition}
|
||||
* @link http://php.net/manual/en/iterator.current.php
|
||||
* @return CFType current Item
|
||||
* @uses $iteratorPosition identify current key
|
||||
*/
|
||||
public function current() {
|
||||
return $this->value[$this->iteratorPosition];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Iterator's current key identified by {@link $iteratorPosition}
|
||||
* @link http://php.net/manual/en/iterator.key.php
|
||||
* @return string key of the current Item
|
||||
* @uses $iteratorPosition identify current key
|
||||
*/
|
||||
public function key() {
|
||||
return $this->iteratorPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment {@link $iteratorPosition} to address next {@see CFType}
|
||||
* @link http://php.net/manual/en/iterator.next.php
|
||||
* @return void
|
||||
* @uses $iteratorPosition increment by 1
|
||||
*/
|
||||
public function next() {
|
||||
$this->iteratorPosition++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if {@link $iteratorPosition} addresses a valid element of {@link $value}
|
||||
* @link http://php.net/manual/en/iterator.valid.php
|
||||
* @return boolean true if current position is valid, false else
|
||||
* @uses $iteratorPosition test if within {@link $iteratorKeys}
|
||||
* @uses $iteratorPosition test if within {@link $value}
|
||||
*/
|
||||
public function valid() {
|
||||
return isset($this->value[$this->iteratorPosition]);
|
||||
}
|
||||
|
||||
/************************************************************************************************
|
||||
* ArrayAccess I N T E R F A C E
|
||||
************************************************************************************************/
|
||||
|
||||
/**
|
||||
* Determine if the array's key exists
|
||||
* @param string $key the key to check
|
||||
* @return bool true if the offset exists, false if not
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
|
||||
* @uses $value to check if $key exists
|
||||
* @author Sean Coates <sean@php.net>
|
||||
*/
|
||||
public function offsetExists($key) {
|
||||
return isset($this->value[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a specific key from the CFArray
|
||||
* @param string $key the key to check
|
||||
* @return mixed the value associated with the key; null if the key is not found
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetget.php
|
||||
* @uses get() to get the key's value
|
||||
* @author Sean Coates <sean@php.net>
|
||||
*/
|
||||
public function offsetGet($key) {
|
||||
return $this->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value in the array
|
||||
* @param string $key the key to set
|
||||
* @param string $value the value to set
|
||||
* @return void
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetset.php
|
||||
* @uses setValue() to set the key's new value
|
||||
* @author Sean Coates <sean@php.net>
|
||||
*/
|
||||
public function offsetSet($key, $value) {
|
||||
return $this->setValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsets a value in the array
|
||||
* <b>Note:</b> this dummy does nothing
|
||||
* @param string $key the key to set
|
||||
* @return void
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
|
||||
* @author Sean Coates <sean@php.net>
|
||||
*/
|
||||
public function offsetUnset($key) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Type of CFPropertyList
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
* @subpackage plist.types
|
||||
*/
|
||||
class CFDictionary extends CFType implements Iterator {
|
||||
/**
|
||||
* Position of iterator {@link http://php.net/manual/en/class.iterator.php}
|
||||
* @var integer
|
||||
*/
|
||||
protected $iteratorPosition = 0;
|
||||
|
||||
/**
|
||||
* List of Keys for numerical iterator access {@link http://php.net/manual/en/class.iterator.php}
|
||||
* @var array
|
||||
*/
|
||||
protected $iteratorKeys = null;
|
||||
|
||||
|
||||
/**
|
||||
* Create new CFType.
|
||||
* @param array $value Value of CFType
|
||||
*/
|
||||
public function __construct($value=array()) {
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CFType's value
|
||||
* <b>Note:</b> this dummy does nothing
|
||||
* @return void
|
||||
*/
|
||||
public function setValue($value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add CFType to collection.
|
||||
* @param string $key Key to add to collection
|
||||
* @param CFType $value CFType to add to collection, defaults to null which results in an empty {@link CFString}
|
||||
* @return void
|
||||
* @uses $value for adding $key $value pair
|
||||
*/
|
||||
public function add($key, CFType $value=null) {
|
||||
// anything but CFType is null, null is an empty string - sad but true
|
||||
if( !$value )
|
||||
$value = new CFString();
|
||||
|
||||
$this->value[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CFType from collection.
|
||||
* @param string $key Key of CFType to retrieve from collection
|
||||
* @return CFType CFType found at $key, null else
|
||||
* @uses $value for retrieving CFType of $key
|
||||
*/
|
||||
public function get($key) {
|
||||
if(isset($this->value[$key])) return $this->value[$key];
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic getter (magic)
|
||||
* @param integer $key Key of CFType to retrieve from collection
|
||||
* @return CFType CFType found at $key, null else
|
||||
* @link http://php.net/oop5.overloading
|
||||
* @uses get() to retrieve the key's value
|
||||
* @author Sean Coates <sean@php.net>
|
||||
*/
|
||||
public function __get($key) {
|
||||
return $this->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove CFType from collection.
|
||||
* @param string $key Key of CFType to removes from collection
|
||||
* @return CFType removed CFType, null else
|
||||
* @uses $value for removing CFType of $key
|
||||
*/
|
||||
public function del($key) {
|
||||
if(isset($this->value[$key])) unset($this->value[$key]);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* S E R I A L I Z I N G
|
||||
************************************************************************************************/
|
||||
|
||||
/**
|
||||
* Get XML-Node.
|
||||
* @param DOMDocument $doc DOMDocument to create DOMNode in
|
||||
* @param string $nodeName For compatibility reasons; just ignore it
|
||||
* @return DOMNode <dict>-Element
|
||||
*/
|
||||
public function toXML(DOMDocument $doc,$nodeName="") {
|
||||
$node = $doc->createElement('dict');
|
||||
|
||||
foreach($this->value as $key => $value) {
|
||||
$node->appendChild($doc->createElement('key', $key));
|
||||
$node->appendChild($value->toXML($doc));
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert value to binary representation
|
||||
* @param CFBinaryPropertyList The binary property list object
|
||||
* @return The offset in the object table
|
||||
*/
|
||||
public function toBinary(CFBinaryPropertyList &$bplist) {
|
||||
return $bplist->dictToBinary($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CFType's value.
|
||||
* @return array primitive value
|
||||
* @uses $value for retrieving primitive of CFType
|
||||
*/
|
||||
public function toArray() {
|
||||
$a = array();
|
||||
|
||||
foreach($this->value as $key => $value) $a[$key] = $value->toArray();
|
||||
return $a;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* I T E R A T O R I N T E R F A C E
|
||||
************************************************************************************************/
|
||||
|
||||
/**
|
||||
* Rewind {@link $iteratorPosition} to first position (being 0)
|
||||
* @link http://php.net/manual/en/iterator.rewind.php
|
||||
* @return void
|
||||
* @uses $iteratorPosition set to 0
|
||||
* @uses $iteratorKeys store keys of {@link $value}
|
||||
*/
|
||||
public function rewind() {
|
||||
$this->iteratorPosition = 0;
|
||||
$this->iteratorKeys = array_keys($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Iterator's current {@link CFType} identified by {@link $iteratorPosition}
|
||||
* @link http://php.net/manual/en/iterator.current.php
|
||||
* @return CFType current Item
|
||||
* @uses $iteratorPosition identify current key
|
||||
* @uses $iteratorKeys identify current value
|
||||
*/
|
||||
public function current() {
|
||||
return $this->value[$this->iteratorKeys[$this->iteratorPosition]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Iterator's current key identified by {@link $iteratorPosition}
|
||||
* @link http://php.net/manual/en/iterator.key.php
|
||||
* @return string key of the current Item
|
||||
* @uses $iteratorPosition identify current key
|
||||
* @uses $iteratorKeys identify current value
|
||||
*/
|
||||
public function key() {
|
||||
return $this->iteratorKeys[$this->iteratorPosition];
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment {@link $iteratorPosition} to address next {@see CFType}
|
||||
* @link http://php.net/manual/en/iterator.next.php
|
||||
* @return void
|
||||
* @uses $iteratorPosition increment by 1
|
||||
*/
|
||||
public function next() {
|
||||
$this->iteratorPosition++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if {@link $iteratorPosition} addresses a valid element of {@link $value}
|
||||
* @link http://php.net/manual/en/iterator.valid.php
|
||||
* @return boolean true if current position is valid, false else
|
||||
* @uses $iteratorPosition test if within {@link $iteratorKeys}
|
||||
* @uses $iteratorPosition test if within {@link $value}
|
||||
*/
|
||||
public function valid() {
|
||||
return isset($this->iteratorKeys[$this->iteratorPosition]) && isset($this->value[$this->iteratorKeys[$this->iteratorPosition]]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# eof
|
||||
|
@ -1,4 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* LICENSE
|
||||
*
|
||||
* This file is part of CFPropertyList.
|
||||
*
|
||||
* The PHP implementation of Apple's PropertyList can handle XML PropertyLists
|
||||
* as well as binary PropertyLists. It offers functionality to easily convert
|
||||
* data between worlds, e.g. recalculating timestamps from unix epoch to apple
|
||||
* epoch and vice versa. A feature to automagically create (guess) the plist
|
||||
* structure from a normal PHP data structure will help you dump your data to
|
||||
* plist in no time.
|
||||
*
|
||||
* Copyright (c) 2018 Teclib'
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @copyright Copyright © 2018 Teclib
|
||||
* @package plist
|
||||
* @license MIT
|
||||
* @link https://github.com/TECLIB/CFPropertyList/
|
||||
* @link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace CFPropertyList;
|
||||
|
||||
use DateTime;
|
||||
use Iterator;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* CFTypeDetector
|
||||
@ -7,53 +55,51 @@
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
* @subpackage plist.types
|
||||
* @example example-create-02.php Using {@link CFTypeDetector}
|
||||
* @example example-create-03.php Using {@link CFTypeDetector} with {@link CFDate} and {@link CFData}
|
||||
* @example example-create-04.php Using and extended {@link CFTypeDetector}
|
||||
* @example example-create-02.php Using CFTypeDetector
|
||||
* @example example-create-03.php Using CFTypeDetector with CFDate and CFData
|
||||
* @example example-create-04.php Using and extended CFTypeDetector
|
||||
*/
|
||||
|
||||
namespace CFPropertyList;
|
||||
use \DateTime, \Iterator;
|
||||
|
||||
class CFTypeDetector {
|
||||
class CFTypeDetector
|
||||
{
|
||||
|
||||
/**
|
||||
* flag stating if all arrays should automatically be converted to {@link CFDictionary}
|
||||
* flag stating if all arrays should automatically be converted to CFDictionary
|
||||
* @var boolean
|
||||
*/
|
||||
protected $autoDictionary = false;
|
||||
protected $autoDictionary = false;
|
||||
|
||||
/**
|
||||
* flag stating if exceptions should be suppressed or thrown
|
||||
* @var boolean
|
||||
*/
|
||||
protected $suppressExceptions = false;
|
||||
protected $suppressExceptions = false;
|
||||
|
||||
/**
|
||||
* name of a method that will be used for array to object conversations
|
||||
* @var callable
|
||||
*/
|
||||
protected $objectToArrayMethod = null;
|
||||
protected $objectToArrayMethod = null;
|
||||
|
||||
/**
|
||||
* flag stating if "123.23" should be converted to float (true) or preserved as string (false)
|
||||
* @var boolean
|
||||
*/
|
||||
protected $castNumericStrings = true;
|
||||
protected $castNumericStrings = true;
|
||||
|
||||
|
||||
/**
|
||||
* Create new CFTypeDetector
|
||||
* @param array $options Configuration for casting values [autoDictionary, suppressExceptions, objectToArrayMethod, castNumericStrings]
|
||||
*/
|
||||
public function __construct(array $options=array()) {
|
||||
//$autoDicitionary=false,$suppressExceptions=false,$objectToArrayMethod=null
|
||||
foreach ($options as $key => $value) {
|
||||
if (property_exists($this, $key)) {
|
||||
$this->$key = $value;
|
||||
}
|
||||
public function __construct(array $options = array())
|
||||
{
|
||||
//$autoDicitionary=false,$suppressExceptions=false,$objectToArrayMethod=null
|
||||
foreach ($options as $key => $value) {
|
||||
if (property_exists($this, $key)) {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if an array is associative or numerical.
|
||||
@ -61,30 +107,32 @@ class CFTypeDetector {
|
||||
* @param array $value Array to check indexes of
|
||||
* @return boolean true if array is associative, false if array has numeric indexes
|
||||
*/
|
||||
protected function isAssociativeArray($value) {
|
||||
$numericKeys = true;
|
||||
$i = 0;
|
||||
foreach($value as $key => $v) {
|
||||
if($i !== $key) {
|
||||
$numericKeys = false;
|
||||
break;
|
||||
}
|
||||
$i++;
|
||||
protected function isAssociativeArray($value)
|
||||
{
|
||||
$numericKeys = true;
|
||||
$i = 0;
|
||||
foreach ($value as $key => $v) {
|
||||
if ($i !== $key) {
|
||||
$numericKeys = false;
|
||||
break;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
return !$numericKeys;
|
||||
}
|
||||
return !$numericKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default value
|
||||
* @return CFType the default value to return if no suitable type could be determined
|
||||
*/
|
||||
protected function defaultValue() {
|
||||
return new CFString();
|
||||
}
|
||||
protected function defaultValue()
|
||||
{
|
||||
return new CFString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create CFType-structure by guessing the data-types.
|
||||
* {@link CFArray}, {@link CFDictionary}, {@link CFBoolean}, {@link CFNumber} and {@link CFString} can be created, {@link CFDate} and {@link CFData} cannot.
|
||||
* CFArray, {@link CFDictionary}, {@link CFBoolean}, {@link CFNumber} and {@link CFString} can be created, {@link CFDate} and {@link CFData} cannot.
|
||||
* <br /><b>Note:</b>Distinguishing between {@link CFArray} and {@link CFDictionary} is done by examining the keys.
|
||||
* Keys must be strictly incrementing integers to evaluate to a {@link CFArray}.
|
||||
* Since PHP does not offer a function to test for associative arrays,
|
||||
@ -94,92 +142,98 @@ class CFTypeDetector {
|
||||
* <br /><b>Note:</b> If $value is an instance of CFType it is simply returned.
|
||||
* <br /><b>Note:</b> If $value is neither a CFType, array, numeric, boolean nor string, it is omitted.
|
||||
* @param mixed $value Value to convert to CFType
|
||||
* @param boolean $autoDictionary if true {@link CFArray}-detection is bypassed and arrays will be returned as {@link CFDictionary}.
|
||||
* @return CFType CFType based on guessed type
|
||||
* @uses isAssociativeArray() to check if an array only has numeric indexes
|
||||
*/
|
||||
public function toCFType($value) {
|
||||
switch(true) {
|
||||
case $value instanceof CFType:
|
||||
return $value;
|
||||
break;
|
||||
public function toCFType($value)
|
||||
{
|
||||
switch (true) {
|
||||
case $value instanceof CFType:
|
||||
return $value;
|
||||
break;
|
||||
|
||||
case is_object($value):
|
||||
// DateTime should be CFDate
|
||||
if(class_exists( 'DateTime' ) && $value instanceof DateTime){
|
||||
return new CFDate($value->getTimestamp());
|
||||
case is_object($value):
|
||||
// DateTime should be CFDate
|
||||
if ($value instanceof DateTime) {
|
||||
return new CFDate($value->getTimestamp());
|
||||
}
|
||||
|
||||
// convert possible objects to arrays, arrays will be arrays
|
||||
if ($this->objectToArrayMethod && is_callable(array($value, $this->objectToArrayMethod))) {
|
||||
$value = call_user_func(array( $value, $this->objectToArrayMethod ));
|
||||
} else if ($value instanceof stdClass) {
|
||||
$value = (array) $value;
|
||||
}
|
||||
|
||||
if (!is_array($value)) {
|
||||
if ($this->suppressExceptions) {
|
||||
return $this->defaultValue();
|
||||
}
|
||||
|
||||
throw new PListException('Could not determine CFType for object of type '. get_class($value));
|
||||
}
|
||||
/* break; omitted */
|
||||
|
||||
case $value instanceof Iterator:
|
||||
case is_array($value):
|
||||
// test if $value is simple or associative array
|
||||
if (!$this->autoDictionary) {
|
||||
if (!$this->isAssociativeArray($value)) {
|
||||
$t = new CFArray();
|
||||
foreach ($value as $v) {
|
||||
$t->add($this->toCFType($v));
|
||||
}
|
||||
return $t;
|
||||
}
|
||||
}
|
||||
|
||||
$t = new CFDictionary();
|
||||
foreach ($value as $k => $v) {
|
||||
$t->add($k, $this->toCFType($v));
|
||||
}
|
||||
|
||||
return $t;
|
||||
break;
|
||||
|
||||
case is_bool($value):
|
||||
return new CFBoolean($value);
|
||||
break;
|
||||
|
||||
case is_null($value):
|
||||
return new CFString();
|
||||
break;
|
||||
|
||||
case is_resource($value):
|
||||
if ($this->suppressExceptions) {
|
||||
return $this->defaultValue();
|
||||
}
|
||||
|
||||
throw new PListException('Could not determine CFType for resource of type '. get_resource_type($value));
|
||||
break;
|
||||
|
||||
case is_numeric($value):
|
||||
if (!$this->castNumericStrings && is_string($value)) {
|
||||
return new CFString($value);
|
||||
}
|
||||
|
||||
return new CFNumber($value);
|
||||
break;
|
||||
|
||||
case is_string($value):
|
||||
if (strpos($value, "\x00") !== false) {
|
||||
return new CFData($value);
|
||||
}
|
||||
return new CFString($value);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if ($this->suppressExceptions) {
|
||||
return $this->defaultValue();
|
||||
}
|
||||
|
||||
throw new PListException('Could not determine CFType for '. gettype($value));
|
||||
break;
|
||||
}
|
||||
|
||||
// convert possible objects to arrays, arrays will be arrays
|
||||
if($this->objectToArrayMethod && is_callable(array($value, $this->objectToArrayMethod))){
|
||||
$value = call_user_func( array( $value, $this->objectToArrayMethod ) );
|
||||
}
|
||||
|
||||
if(!is_array($value)){
|
||||
if($this->suppressExceptions)
|
||||
return $this->defaultValue();
|
||||
|
||||
throw new PListException('Could not determine CFType for object of type '. get_class($value));
|
||||
}
|
||||
/* break; omitted */
|
||||
|
||||
case $value instanceof Iterator:
|
||||
case is_array($value):
|
||||
// test if $value is simple or associative array
|
||||
if(!$this->autoDictionary) {
|
||||
if(!$this->isAssociativeArray($value)) {
|
||||
$t = new CFArray();
|
||||
foreach($value as $v) $t->add($this->toCFType($v));
|
||||
return $t;
|
||||
}
|
||||
}
|
||||
|
||||
$t = new CFDictionary();
|
||||
foreach($value as $k => $v) $t->add($k, $this->toCFType($v));
|
||||
|
||||
return $t;
|
||||
break;
|
||||
|
||||
case is_bool($value):
|
||||
return new CFBoolean($value);
|
||||
break;
|
||||
|
||||
case is_null($value):
|
||||
return new CFString();
|
||||
break;
|
||||
|
||||
case is_resource($value):
|
||||
if ($this->suppressExceptions) {
|
||||
return $this->defaultValue();
|
||||
}
|
||||
|
||||
throw new PListException('Could not determine CFType for resource of type '. get_resource_type($value));
|
||||
break;
|
||||
|
||||
case is_numeric($value):
|
||||
if (!$this->castNumericStrings && is_string($value)) {
|
||||
return new CFString($value);
|
||||
}
|
||||
|
||||
return new CFNumber($value);
|
||||
break;
|
||||
|
||||
case is_string($value):
|
||||
if(strpos($value, "\x00") !== false) {
|
||||
return new CFData($value);
|
||||
}
|
||||
return new CFString($value);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if ($this->suppressExceptions) {
|
||||
return $this->defaultValue();
|
||||
}
|
||||
|
||||
throw new PListException('Could not determine CFType for '. gettype($value));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
68
lib/plist/classes/CFPropertyList/CFUid.php
Normal file
68
lib/plist/classes/CFPropertyList/CFUid.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* LICENSE
|
||||
*
|
||||
* This file is part of CFPropertyList.
|
||||
*
|
||||
* The PHP implementation of Apple's PropertyList can handle XML PropertyLists
|
||||
* as well as binary PropertyLists. It offers functionality to easily convert
|
||||
* data between worlds, e.g. recalculating timestamps from unix epoch to apple
|
||||
* epoch and vice versa. A feature to automagically create (guess) the plist
|
||||
* structure from a normal PHP data structure will help you dump your data to
|
||||
* plist in no time.
|
||||
*
|
||||
* Copyright (c) 2018 Teclib'
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @copyright Copyright © 2018 Teclib
|
||||
* @package plist
|
||||
* @license MIT
|
||||
* @link https://github.com/TECLIB/CFPropertyList/
|
||||
* @link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace CFPropertyList;
|
||||
|
||||
use \DOMDocument;
|
||||
use \Iterator;
|
||||
use \ArrayAccess;
|
||||
|
||||
/**
|
||||
* @example example-create-02.php Using CFTypeDetector
|
||||
* @example example-create-03.php Using CFTypeDetector with CFDate and CFData
|
||||
* @example example-create-04.php Using and extended CFTypeDetector
|
||||
*/
|
||||
class CFUid extends CFType
|
||||
{
|
||||
public function toXML(DOMDocument $doc, $nodeName = "")
|
||||
{
|
||||
$obj = new CFDictionary(array('CF$UID' => new CFNumber($this->value)));
|
||||
return $obj->toXml($doc);
|
||||
}
|
||||
|
||||
public function toBinary(CFBinaryPropertyList &$bplist)
|
||||
{
|
||||
return $bplist->uidToBinary($this->value);
|
||||
}
|
||||
}
|
@ -1,98 +1,133 @@
|
||||
<?php
|
||||
/**
|
||||
* CFPropertyList
|
||||
* {@link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists}
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
* @version $Id$
|
||||
* LICENSE
|
||||
*
|
||||
* This file is part of CFPropertyList.
|
||||
*
|
||||
* The PHP implementation of Apple's PropertyList can handle XML PropertyLists
|
||||
* as well as binary PropertyLists. It offers functionality to easily convert
|
||||
* data between worlds, e.g. recalculating timestamps from unix epoch to apple
|
||||
* epoch and vice versa. A feature to automagically create (guess) the plist
|
||||
* structure from a normal PHP data structure will help you dump your data to
|
||||
* plist in no time.
|
||||
*
|
||||
* Copyright (c) 2018 Teclib'
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @copyright Copyright © 2018 Teclib
|
||||
* @package plist
|
||||
* @license MIT
|
||||
* @link https://github.com/TECLIB/CFPropertyList/
|
||||
* @link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace CFPropertyList;
|
||||
|
||||
/**
|
||||
* Basic Input / Output Exception
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
*/
|
||||
class IOException extends \Exception {
|
||||
class IOException extends \Exception
|
||||
{
|
||||
/**
|
||||
* Flag telling the File could not be found
|
||||
*/
|
||||
const NOT_FOUND = 1;
|
||||
|
||||
const NOT_FOUND = 1;
|
||||
|
||||
/**
|
||||
* Flag telling the File is not readable
|
||||
*/
|
||||
const NOT_READABLE = 2;
|
||||
|
||||
const NOT_READABLE = 2;
|
||||
|
||||
/**
|
||||
* Flag telling the File is not writable
|
||||
*/
|
||||
const NOT_WRITABLE = 3;
|
||||
const NOT_WRITABLE = 3;
|
||||
|
||||
/**
|
||||
* Flag telling there was a read error
|
||||
*/
|
||||
const READ_ERROR = 4;
|
||||
const READ_ERROR = 4;
|
||||
|
||||
/**
|
||||
* Flag telling there was a read error
|
||||
*/
|
||||
const WRITE_ERROR = 5;
|
||||
const WRITE_ERROR = 5;
|
||||
|
||||
/**
|
||||
* Create new IOException
|
||||
* @param string $path Source of the problem
|
||||
* @param integer $type Type of the problem
|
||||
*/
|
||||
public function __construct($path, $type=null) {
|
||||
parent::__construct( $path, $type );
|
||||
}
|
||||
|
||||
public function __construct($path, $type = null)
|
||||
{
|
||||
parent::__construct($path, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new FileNotFound-Exception
|
||||
* @param string $path Source of the problem
|
||||
* @return IOException new FileNotFound-Exception
|
||||
*/
|
||||
public static function notFound($path) {
|
||||
return new IOException( $path, self::NOT_FOUND );
|
||||
}
|
||||
public static function notFound($path)
|
||||
{
|
||||
return new IOException($path, self::NOT_FOUND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new FileNotReadable-Exception
|
||||
* @param string $path Source of the problem
|
||||
* @return IOException new FileNotReadable-Exception
|
||||
*/
|
||||
public static function notReadable($path) {
|
||||
return new IOException( $path, self::NOT_READABLE );
|
||||
}
|
||||
public static function notReadable($path)
|
||||
{
|
||||
return new IOException($path, self::NOT_READABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new FileNotWritable-Exception
|
||||
* @param string $path Source of the problem
|
||||
* @return IOException new FileNotWritable-Exception
|
||||
*/
|
||||
public static function notWritable($path) {
|
||||
return new IOException( $path, self::NOT_WRITABLE );
|
||||
}
|
||||
public static function notWritable($path)
|
||||
{
|
||||
return new IOException($path, self::NOT_WRITABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new ReadError-Exception
|
||||
* @param string $path Source of the problem
|
||||
* @return IOException new ReadError-Exception
|
||||
*/
|
||||
public static function readError($path) {
|
||||
return new IOException( $path, self::READ_ERROR );
|
||||
}
|
||||
public static function readError($path)
|
||||
{
|
||||
return new IOException($path, self::READ_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new WriteError-Exception
|
||||
* @param string $path Source of the problem
|
||||
* @return IOException new WriteError-Exception
|
||||
*/
|
||||
public static function writeError($path) {
|
||||
return new IOException( $path, self::WRITE_ERROR );
|
||||
}
|
||||
public static function writeError($path)
|
||||
{
|
||||
return new IOException($path, self::WRITE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,22 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* CFPropertyList
|
||||
* {@link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists}
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
* @version $Id$
|
||||
* LICENSE
|
||||
*
|
||||
* This file is part of CFPropertyList.
|
||||
*
|
||||
* The PHP implementation of Apple's PropertyList can handle XML PropertyLists
|
||||
* as well as binary PropertyLists. It offers functionality to easily convert
|
||||
* data between worlds, e.g. recalculating timestamps from unix epoch to apple
|
||||
* epoch and vice versa. A feature to automagically create (guess) the plist
|
||||
* structure from a normal PHP data structure will help you dump your data to
|
||||
* plist in no time.
|
||||
*
|
||||
* Copyright (c) 2018 Teclib'
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @copyright Copyright © 2018 Teclib
|
||||
* @package plist
|
||||
* @license MIT
|
||||
* @link https://github.com/TECLIB/CFPropertyList/
|
||||
* @link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace CFPropertyList;
|
||||
|
||||
/**
|
||||
* Exception for errors with the PList format
|
||||
* @author Rodney Rehm <rodney.rehm@medialize.de>
|
||||
* @author Christian Kruse <cjk@wwwtech.de>
|
||||
* @package plist
|
||||
*/
|
||||
class PListException extends \Exception {
|
||||
class PListException extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,7 +5,8 @@ Downloaded last release from: https://github.com/TECLIB/CFPropertyList/releases/
|
||||
|
||||
Import procedure:
|
||||
|
||||
- Copy all the files from the CFPropertyList-XXX folder to into lib/plist and remove following files/dirs.
|
||||
- Copy all the files from the CFPropertyList-XXX/src/CFPropertyList folder into lib/plist/classes/CFPropertyList.
|
||||
- Copy all the .md files from CFPropertyList-XXX to lib/plist/.
|
||||
|
||||
Removed:
|
||||
* .gitignore
|
||||
@ -14,12 +15,7 @@ Removed:
|
||||
* examples
|
||||
* tests
|
||||
|
||||
Local changes:
|
||||
(always verify if the changes below are already fixed by the
|
||||
next version to import or they need to be re-applied manually)
|
||||
* PHP 7.4 comp: bf527c8 - Partially applied https://github.com/TECLIB/CFPropertyList/pull/61
|
||||
|
||||
Added:
|
||||
* readme_moodle.txt
|
||||
|
||||
Downloaded version: 2.0.1
|
||||
Downloaded version: 2.0.2
|
||||
|
@ -337,7 +337,7 @@
|
||||
<location>plist</location>
|
||||
<name>plist</name>
|
||||
<license>MIT</license>
|
||||
<version>2.0.1</version>
|
||||
<version>2.0.2</version>
|
||||
</library>
|
||||
<library>
|
||||
<location>zipstream</location>
|
||||
|
Loading…
x
Reference in New Issue
Block a user