├── .gitignore
├── composer.json
├── .travis.yml
├── examples
├── iframe.html
├── alert
│ ├── alert.js
│ └── alert.css
└── iframe_preview_edits.html
├── LICENSE
├── README.md
├── Link.php
├── proxy.php
└── tests
└── LinkTest.php
/.gitignore:
--------------------------------------------------------------------------------
1 | composer.lock
2 | # Dependencies
3 | vendor/
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "require-dev": {
3 | "phpunit/phpunit": "*"
4 | }
5 | }
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | php:
3 | - 5.4
4 | - 5.5
5 | - 5.6
6 | script: "phpunit tests"
7 |
--------------------------------------------------------------------------------
/examples/iframe.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/examples/alert/alert.js:
--------------------------------------------------------------------------------
1 | (function($){
2 | $.fn.alert = function(){
3 | return this.each(function(){
4 | var self = $(this);
5 | self.on('click','.close',function(){
6 | self.addClass('close');
7 | });
8 | self.on('transitionend webkitTransitionEnd oTransitionEnd', function(){
9 | self.remove();
10 | });
11 | });
12 | };
13 | }(jQuery))
--------------------------------------------------------------------------------
/examples/alert/alert.css:
--------------------------------------------------------------------------------
1 | .alert{
2 | padding:10px;
3 | background-color:#bbb;
4 | color:#fff;
5 | font-size:.9em;
6 | opacity:1;
7 | -webkit-transition:opacity 1s ease-in;
8 | -moz-transition:opacity 1s ease-in;
9 | -o-transition:opacity 1s ease-in;
10 | transition:opacity 1s ease-in;
11 | }
12 | .alert .close{
13 | float:right;
14 | font-size:2em;
15 | text-decoration:none;
16 | position:relative;
17 | }
18 | .alert.success{
19 | background-color:#55aa44;
20 | }
21 | .alert.warning{
22 | background-color:#F7FA5C;
23 | color:black;
24 | }
25 | .alert.error{
26 | background-color:#ff7777;
27 | }
28 | .alert.close{
29 | opacity:0;
30 | }
31 | div.alert{
32 | position:fixed;
33 | top:0;
34 | left:0;
35 | right:0;
36 | }
--------------------------------------------------------------------------------
/examples/iframe_preview_edits.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 |
22 |
23 |
24 | This is only a preview and may not always be accurate.
×
25 |
26 |
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Kyle Ladd
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Relative-to-Absolute-Links
2 | Convert all relative links within string to absolute
3 |
4 | [](https://travis-ci.org/kyleladd/Relative-to-Absolute-Links)
5 |
6 |
7 | ## Install Dependencies
8 | ```
9 | composer install
10 | ```
11 |
12 | ## Run tests
13 | ```
14 | vendor/phpunit/phpunit/phpunit tests
15 | ```
16 |
17 | ## Options
18 |
19 | ### url
20 | * Url to get the document of as a string and convert all of its resources from relative to absolute.
21 | * Default:
22 | ```html
23 |
24 | ```
25 |
26 | ### rooturl
27 | * Controls the vertical positioning of the marker relative to the marker location. The change only affects markers subsequently inserted
28 | * Valid Values: {url string}
29 | * Default: "" - fetches the Document Root
30 | ```html
31 |
32 | ```
33 |
34 | ### slashIsRoot
35 | * When a link starts with slash, on a Linux system this typically means go to root while Windows is the current directory. Convert relative link to the appropriate absolute link.
36 | * Valid Values: true, false
37 | * Default: true
38 | ```html
39 |
40 | ```
41 |
42 | ### format
43 | * Output as JSON for $.getJSON() or as html for an iframe .
44 | * Valid Values: json, iframe
45 | * Default: json
46 | ```html
47 |
48 |
56 | ```
--------------------------------------------------------------------------------
/Link.php:
--------------------------------------------------------------------------------
1 | $haystackString,'adjustment'=>$adjustment);
131 | }
132 |
133 | /**
134 | * linkStartsWithDDS
135 | *
136 | * Replace "../" (up a directory) in string with the appropriate absolute url when provided the current url.
137 | *
138 | * @param string $haystackString
139 | * @param int $start
140 | * @param string $absoluteURL
141 | * @param array $slashPositions
142 | * @param int $adjustment
143 | * @return array(string,int)
144 | */
145 | function linkStartsWithDDS($haystackString,$start,$absoluteURL,$slashPositions,$adjustment){
146 | $ddsPos = $start;
147 | $numddsToReplace = 0;
148 | $ddsr = true;
149 | //look for all ../ after the current position in a row
150 | while($ddsr==true){
151 | if(substr($haystackString,$ddsPos,3)=="../"){
152 | $numddsToReplace++;
153 | $ddsPos = intval($ddsPos)+3;
154 | }
155 | else{
156 | $ddsr = false;
157 | }
158 | }
159 | //Replace the all the leading ../ with the corresponding portion of the current directory
160 | $haystackString = substr_replace($haystackString, substr($absoluteURL,0,intval($slashPositions[count($slashPositions)-(intval($numddsToReplace))-1]+1)), $start, 3*intval($numddsToReplace));
161 | $adjustment = intval($slashPositions[count($slashPositions)-(intval($numddsToReplace))-1]+1)-(intval($numddsToReplace)*3)+intval($adjustment);
162 | return array('haystack'=>$haystackString,'adjustment'=>$adjustment);
163 | }
164 |
165 | /**
166 | * linkStartsWithDS
167 | *
168 | * Insert the absolute directory at position in string in place of "./".
169 | *
170 | * @param string $haystackString
171 | * @param int $start
172 | * @param string $theAbsoluteDirectory
173 | * @param int $adjustment
174 | * @return array(string,int)
175 | */
176 | function linkStartsWithDS($haystackString,$start,$theAbsoluteDirectory,$adjustment){
177 | $haystackString = substr_replace($haystackString, $theAbsoluteDirectory, $start, 2);
178 | $adjustment = intval(strlen($theAbsoluteDirectory)-2)+intval($adjustment);
179 | return array('haystack'=>$haystackString,'adjustment'=>$adjustment);
180 | }
181 |
182 | /**
183 | * prependAbsoluteDirectory
184 | *
185 | * Insert the absolute directory at position in string.
186 | *
187 | * @param string $haystackString
188 | * @param int $start
189 | * @param string $theAbsoluteDirectory
190 | * @param int $adjustment
191 | * @return array(string,int)
192 | */
193 | function prependAbsoluteDirectory($haystackString,$start,$theAbsoluteDirectory,$adjustment){
194 | $haystackString = substr_replace($haystackString, $theAbsoluteDirectory, $start, 0);
195 | $adjustment = intval(strlen($theAbsoluteDirectory))+intval($adjustment);
196 | return array('haystack'=>$haystackString,'adjustment'=>$adjustment);
197 | }
198 |
199 | /**
200 | * getTheAbsoluteDirectory
201 | *
202 | * Get the current directory from the url provided.
203 | *
204 | * @param string $theAbsoluteURL
205 | * @return string $theAbsoluteDirectory
206 | */
207 | function getTheAbsoluteDirectory($theAbsoluteURL){
208 | $slashLastPos=0;
209 | while (($slashLastPos = strpos($theAbsoluteURL, "/", $slashLastPos))!== false) {
210 | $slashPositions[] = $slashLastPos;
211 | $slashLastPos = intval($slashLastPos) + 1;
212 | }
213 | //Absolute Directory: beginning of the string to the Last slash (+1 includes the slash in the string)
214 | $theAbsoluteDirectory=substr($theAbsoluteURL, 0, end($slashPositions)+1);
215 | return $theAbsoluteDirectory;
216 | }
217 |
218 | /**
219 | * getResourcePositions
220 | *
221 | * Find the positions of all links to resources within string.
222 | *
223 | * @param string $haystackString
224 | * @return array $matches[0]
225 | */
226 | function getResourcePositions($haystackString){
227 | $pattern = "/(src|href)\s*(=)\s*('|\")/i";
228 | preg_match_all($pattern, $haystackString, $matches, PREG_OFFSET_CAPTURE);
229 | return $matches [0];
230 | }
231 |
232 | /**
233 | * getRootURL
234 | *
235 | * Return the root url from the url given.
236 | *
237 | * @param string $theAbsoluteURL
238 | * @return string
239 | */
240 | function getRootURL($theAbsoluteURL){
241 | $slashpositions = getCharacterPositions($theAbsoluteURL);
242 | return substr($theAbsoluteURL, 0, $slashpositions[2] + 1);
243 | }
244 | function getProtocol($link){
245 | $ssc = strpos($link, "://");
246 | return substr($link, 0, intval($ssc) + 3);
247 | }
248 | function convertStartingSlashes($haystackString,$rootURL,$theAbsoluteDirectory,$start,$startingSlashMeansRoot,$adjustment){
249 | $protocol = getProtocol($rootURL);
250 | $haystackString = substr_replace($haystackString, $protocol, $start, 2);
251 | $adjustment = intval(strlen($protocol)-2)+intval($adjustment);
252 | return array('haystack'=>$haystackString,'adjustment'=>$adjustment);
253 | }
--------------------------------------------------------------------------------
/proxy.php:
--------------------------------------------------------------------------------
1 | and
41 | // are disabled by default, see for more information.
42 | // callback - If specified, the response JSON will be wrapped in this named
43 | // function call. This parameter and are disabled by
44 | // default, see for more information.
45 | // user_agent - This value will be sent to the remote URL request as the
46 | // `User-Agent:` HTTP request header. If omitted, the browser user agent
47 | // will be passed through.
48 | // send_cookies - If send_cookies=1, all cookies will be forwarded through to
49 | // the remote URL request.
50 | // send_session - If send_session=1 and send_cookies=1, the SID cookie will be
51 | // forwarded through to the remote URL request.
52 | // full_headers - If a JSON request and full_headers=1, the JSON response will
53 | // contain detailed header information.
54 | // full_status - If a JSON request and full_status=1, the JSON response will
55 | // contain detailed cURL status information, otherwise it will just contain
56 | // the `http_code` property.
57 | //
58 | // Topic: POST Parameters
59 | //
60 | // All POST parameters are automatically passed through to the remote URL
61 | // request.
62 | //
63 | // Topic: JSON requests
64 | //
65 | // This request will return the contents of the specified url in JSON format.
66 | //
67 | // Request:
68 | //
69 | // > ba-simple-proxy.php?url=http://example.com/
70 | //
71 | // Response:
72 | //
73 | // > { "contents": "...", "headers": {...}, "status": {...} }
74 | //
75 | // JSON object properties:
76 | //
77 | // contents - (String) The contents of the remote URL resource.
78 | // headers - (Object) A hash of HTTP headers returned by the remote URL
79 | // resource.
80 | // status - (Object) A hash of status codes returned by cURL.
81 | //
82 | // Topic: JSONP requests
83 | //
84 | // This request will return the contents of the specified url in JSONP format
85 | // (but only if $enable_jsonp is enabled in the PHP script).
86 | //
87 | // Request:
88 | //
89 | // > ba-simple-proxy.php?url=http://example.com/&callback=foo
90 | //
91 | // Response:
92 | //
93 | // > foo({ "contents": "...", "headers": {...}, "status": {...} })
94 | //
95 | // JSON object properties:
96 | //
97 | // contents - (String) The contents of the remote URL resource.
98 | // headers - (Object) A hash of HTTP headers returned by the remote URL
99 | // resource.
100 | // status - (Object) A hash of status codes returned by cURL.
101 | //
102 | // Topic: Native requests
103 | //
104 | // This request will return the contents of the specified url in the format it
105 | // was received in, including the same content-type and other headers (but only
106 | // if $enable_native is enabled in the PHP script).
107 | //
108 | // Request:
109 | //
110 | // > ba-simple-proxy.php?url=http://example.com/&mode=native
111 | //
112 | // Response:
113 | //
114 | // > ...
115 | //
116 | // Topic: Notes
117 | //
118 | // * Assumes magic_quotes_gpc = Off in php.ini
119 | //
120 | // Topic: Configuration Options
121 | //
122 | // These variables can be manually edited in the PHP file if necessary.
123 | //
124 | // $enable_jsonp - Only enable if you really need to. If you
125 | // install this script on the same server as the page you're calling it
126 | // from, plain JSON will work. Defaults to false.
127 | // $enable_native - You can enable , but you should only do
128 | // this if you also whitelist specific URLs using $valid_url_regex, to avoid
129 | // possible XSS vulnerabilities. Defaults to false.
130 | // $valid_url_regex - This regex is matched against the url parameter to
131 | // ensure that it is valid. This setting only needs to be used if either
132 | // $enable_jsonp or $enable_native are enabled. Defaults to '/.*/' which
133 | // validates all URLs.
134 | //
135 | // ############################################################################
136 |
137 | // Change these configuration options if needed, see above descriptions for info.
138 | $enable_jsonp = false;
139 | $enable_native = true;
140 | $valid_url_regex = '/.*/';
141 |
142 | // ############################################################################
143 | require 'Link.php';
144 | $url = $_GET['url'];
145 | if(isset($_GET['rooturl'])){
146 | $rootURL = $_GET['rooturl'];
147 | }
148 | else{
149 | $rootURL="";
150 | }
151 |
152 | if(isset($_GET['slashIsRoot'])){
153 | $isStartingSlashRoot = $_GET['slashIsRoot'];
154 | }
155 | else{
156 | $isStartingSlashRoot=true;
157 | }
158 | if(isset($_GET['format'])){
159 | $format = $_GET['format'];
160 | }
161 | else{
162 | $format = "json";
163 | }
164 |
165 | $_GET['send_cookies']=true;
166 | $_GET['send_session']=true;
167 | $_GET['full_headers']=false;
168 | $_GET['full_status']=false;
169 | //$_GET['mode']='native';
170 | error_reporting(0);
171 | if ( !$url ) {
172 |
173 | // Passed url not specified.
174 | $contents = 'ERROR: url not specified';
175 | $status = array( 'http_code' => 'ERROR' );
176 |
177 | } else if ( !preg_match( $valid_url_regex, $url ) ) {
178 |
179 | // Passed url doesn't match $valid_url_regex.
180 | $contents = 'ERROR: invalid url';
181 | $status = array( 'http_code' => 'ERROR' );
182 |
183 | } else {
184 | $ch = curl_init( $url );
185 |
186 | if ( strtolower($_SERVER['REQUEST_METHOD']) == 'post' ) {
187 | curl_setopt( $ch, CURLOPT_POST, true );
188 | curl_setopt( $ch, CURLOPT_POSTFIELDS, $_POST );
189 | }
190 |
191 | if ( $_GET['send_cookies'] ) {
192 | $cookie = array();
193 | foreach ( $_COOKIE as $key => $value ) {
194 | $cookie[] = $key . '=' . $value;
195 | }
196 | if ( $_GET['send_session'] ) {
197 | $cookie[] = 'SID';
198 | //$cookie[] = SID;
199 | }
200 | $cookie = implode( '; ', $cookie );
201 |
202 | curl_setopt( $ch, CURLOPT_COOKIE, $cookie );
203 | }
204 |
205 | curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
206 | curl_setopt( $ch, CURLOPT_HEADER, true );
207 | curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
208 |
209 | curl_setopt( $ch, CURLOPT_USERAGENT, $_GET['user_agent'] ? $_GET['user_agent'] : $_SERVER['HTTP_USER_AGENT'] );
210 |
211 | list( $header, $contents ) = preg_split( '/([\r\n][\r\n])\\1/', curl_exec( $ch ), 2 );
212 |
213 | $status = curl_getinfo( $ch );
214 |
215 | curl_close( $ch );
216 | }
217 |
218 | // Split header text into an array.
219 | $header_text = preg_split( '/[\r\n]+/', $header );
220 |
221 | if ( $_GET['mode'] == 'native' ) {
222 | if ( !$enable_native ) {
223 | $contents = 'ERROR: invalid mode';
224 | $status = array( 'http_code' => 'ERROR' );
225 | }
226 |
227 | // Propagate headers to response.
228 | foreach ( $header_text as $header ) {
229 | if ( preg_match( '/^(?:Content-Type|Content-Language|Set-Cookie):/i', $header ) ) {
230 | header( $header );
231 | }
232 | }
233 |
234 | print $contents;
235 |
236 | } else {
237 |
238 | // $data will be serialized into JSON data.
239 | $data = array();
240 |
241 | // Propagate all HTTP headers into the JSON data object.
242 | if ( $_GET['full_headers'] ) {
243 | $data['headers'] = array();
244 |
245 | foreach ( $header_text as $header ) {
246 | preg_match( '/^(.+?):\s+(.*)$/', $header, $matches );
247 | if ( $matches ) {
248 | $data['headers'][ $matches[1] ] = $matches[2];
249 | }
250 | }
251 | }
252 |
253 | // Propagate all cURL request / response info to the JSON data object.
254 | if ( $_GET['full_status'] ) {
255 | $data['status'] = $status;
256 | } else {
257 | $data['status'] = array();
258 | $data['status']['http_code'] = $status['http_code'];
259 | }
260 |
261 | // Set the JSON data object contents, decoding it from JSON if possible.
262 | $decoded_json = json_decode( $contents );
263 | $data['contents'] = $decoded_json ? $decoded_json : $contents;
264 |
265 | // Generate appropriate content-type header.
266 | $is_xhr = strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
267 |
268 | // Get JSONP callback.
269 | $jsonp_callback = $enable_jsonp && isset($_GET['callback']) ? $_GET['callback'] : null;
270 | $contents = $data['contents'];
271 |
272 | $stringstart = strpos($contents,"");
273 | $mystring = substr($contents,$stringstart);
274 | //Types of links
275 | $mystring = convertRelativeToAbsolute($mystring,$url,$isStartingSlashRoot,$rootURL);
276 | // Generate JSON/JSONP string
277 | $json = json_encode( $mystring );
278 | if($format=="html"){
279 | header( 'Content-type: text/html' );
280 | print $mystring;
281 | }
282 | else{
283 | header( 'Content-type: application/' . ( $is_xhr ? 'json' : 'x-javascript' ) );
284 | print $jsonp_callback ? "$jsonp_callback($json)" : $json;
285 | }
286 |
287 | }
288 |
289 | ?>
--------------------------------------------------------------------------------
/tests/LinkTest.php:
--------------------------------------------------------------------------------
1 | assertEquals("http://example.com/",getTheAbsoluteDirectory("http://example.com/"));
9 | $this->assertEquals("http://example.com/",getTheAbsoluteDirectory("http://example.com/index.html"));
10 | $this->assertEquals("http://example.com/posts/",getTheAbsoluteDirectory("http://example.com/posts/"));
11 | $this->assertEquals("http://example.com/posts/",getTheAbsoluteDirectory("http://example.com/posts/post.html"));
12 | }
13 |
14 | public function testIsAbsoluteLink() {
15 | $this->assertEquals(true, isAbsoluteLink("http://",0));
16 | $this->assertEquals(true, isAbsoluteLink("https://",0));
17 | $this->assertEquals(true, isAbsoluteLink("ftp://",0));
18 | $this->assertEquals(true, isAbsoluteLink("mailto",0));
19 | $this->assertEquals(true, isAbsoluteLink("mailto:someone@example.com",0));
20 | $this->assertEquals(true, isAbsoluteLink("http://example.com/",0));
21 | $this->assertEquals(true, isAbsoluteLink("https://example.com/",0));
22 | $this->assertEquals(true, isAbsoluteLink("ftp://example.com",0));
23 | $this->assertEquals(true, isAbsoluteLink("#",0));
24 | $this->assertEquals(false, isAbsoluteLink("index.html",0));
25 | $this->assertEquals(false, isAbsoluteLink("/home.html",0));
26 | $this->assertEquals(false, isAbsoluteLink("/posts/post.html",0));
27 | $this->assertEquals(false, isAbsoluteLink("posts/post.html",0));
28 | $this->assertEquals(false, isAbsoluteLink("//www.youtube.com",0));
29 | }
30 |
31 | public function testIsAbsoluteLinkCaseInsensitive() {
32 | $this->assertEquals(true, isAbsoluteLink("Http://",0));
33 | $this->assertEquals(true, isAbsoluteLink("Https://",0));
34 | $this->assertEquals(true, isAbsoluteLink("Ftp://",0));
35 | $this->assertEquals(true, isAbsoluteLink("MailTo",0));
36 | $this->assertEquals(true, isAbsoluteLink("MailTo:someone@example.com",0));
37 | $this->assertEquals(true, isAbsoluteLink("Http://example.com/",0));
38 | $this->assertEquals(true, isAbsoluteLink("Https://example.com/",0));
39 | $this->assertEquals(true, isAbsoluteLink("Ftp://example.com",0));
40 | $this->assertEquals(true, isAbsoluteLink("#",0));
41 | }
42 |
43 | public function testStartingSlashTrue(){
44 | $link = "/post/index.php";
45 | $rootURL = "http://example.com/";
46 | $theAbsoluteDirectory = "http://example.com/";
47 | // starting slash is root
48 | $result = linkStartsWithSlash($link,$rootURL,$theAbsoluteDirectory,0,true,0);
49 | $this->assertEquals("http://example.com/post/index.php",$result["haystack"]);
50 | $this->assertEquals(18,$result["adjustment"]);
51 | }
52 |
53 | public function testStartingSlashTrueURLNotRootDirectory(){
54 | $link = "/post/index.php";
55 | $rootURL = "http://example.com/";
56 | $theAbsoluteDirectory = "http://example.com/posts/";
57 | $result = linkStartsWithSlash($link,$rootURL,$theAbsoluteDirectory,0,true,0);
58 | $this->assertEquals("http://example.com/post/index.php",$result["haystack"]);
59 | $this->assertEquals(18,$result["adjustment"]);
60 | }
61 |
62 | public function testStartingSlashFalse(){
63 | $link = "/post/index.php";
64 | $rootURL = "http://example.com/";
65 | $theAbsoluteDirectory = "http://example.com/";
66 | $result = linkStartsWithSlash($link,$rootURL,$theAbsoluteDirectory,0,false,0);
67 | $this->assertEquals("http://example.com/post/index.php",$result["haystack"]);
68 | $this->assertEquals(18,$result["adjustment"]);
69 | }
70 |
71 | public function testStartingSlashFalseURLNotRootDirectory(){
72 | $link = "/post/index.php";
73 | $rootURL = "http://example.com/";
74 | $theAbsoluteDirectory = "http://example.com/posts/";
75 | $result = linkStartsWithSlash($link,$rootURL,$theAbsoluteDirectory,0,false,0);
76 | $this->assertEquals("http://example.com/posts/post/index.php",$result["haystack"]);
77 | $this->assertEquals(24,$result["adjustment"]);
78 | }
79 |
80 | public function testStartsWithDS(){
81 | $link = "./post/index.php";
82 | $theAbsoluteDirectory = "http://example.com/posts/";
83 | $result = linkStartsWithDS($link,0,$theAbsoluteDirectory,0);
84 | $this->assertEquals("http://example.com/posts/post/index.php",$result["haystack"]);
85 | $this->assertEquals(23,$result["adjustment"]);
86 | }
87 |
88 | public function testStartsWithGETParamsOnRoot(){
89 | $link = "?test=example";
90 | $absoluteURL = "http://example.com/posts/";
91 | $result = prependAbsoluteDirectory($link,0,$absoluteURL,0);
92 | $this->assertEquals("http://example.com/posts/?test=example",$result["haystack"]);
93 | $this->assertEquals(25,$result["adjustment"]);
94 | }
95 |
96 | public function testStartsWithGETParamsNotOnRoot(){
97 | $link = "?test=example";
98 | $absoluteURL = "http://example.com/posts/index.php";
99 | $result = prependAbsoluteDirectory($link,0,$absoluteURL,0);
100 | $this->assertEquals("http://example.com/posts/index.php?test=example",$result["haystack"]);
101 | $this->assertEquals(34,$result["adjustment"]);
102 | }
103 |
104 | public function testPrependAbsoluteDirectory(){
105 | $link = "myotherpage.html";
106 | $theAbsoluteDirectory = "http://example.com/posts/";
107 | $result = prependAbsoluteDirectory($link,0,$theAbsoluteDirectory,0);
108 | $this->assertEquals("http://example.com/posts/myotherpage.html",$result["haystack"]);
109 | $this->assertEquals(25,$result["adjustment"]);
110 | }
111 |
112 | public function testgetCharacterPositions(){
113 | $absoluteURL = "http://example.com/posts/post/comments/comment/index.php";
114 | $slashPositions = getCharacterPositions($absoluteURL);
115 | $this->assertEquals(array(5,6,18,24,29,38,46),$slashPositions);
116 | }
117 |
118 | public function testLinkStartWithDDS(){
119 | $link = "../myotherpage.html";
120 | $slashLastPos = 0;
121 | $absoluteURL = "http://example.com/a/b/c/d/e/f/mypage.html";
122 | $slashPositions = getCharacterPositions($absoluteURL);
123 | $theAbsoluteDirectory = getTheAbsoluteDirectory($absoluteURL);
124 | $result = linkStartsWithDDS($link,0,$absoluteURL,$slashPositions,0);
125 | $this->assertEquals("http://example.com/a/b/c/d/e/myotherpage.html",$result["haystack"]);
126 | $this->assertEquals(26,$result["adjustment"]);
127 | $link = "../../myotherpage.html";
128 | $result = linkStartsWithDDS($link,0,$absoluteURL,$slashPositions,0);
129 | $this->assertEquals("http://example.com/a/b/c/d/myotherpage.html",$result["haystack"]);
130 | $this->assertEquals(21,$result["adjustment"]);
131 | $link = "../../../myotherpage.html";
132 | $result = linkStartsWithDDS($link,0,$absoluteURL,$slashPositions,0);
133 | $this->assertEquals("http://example.com/a/b/c/myotherpage.html",$result["haystack"]);
134 | $this->assertEquals(16,$result["adjustment"]);
135 | $link = "../../../../myotherpage.html";
136 | $result = linkStartsWithDDS($link,0,$absoluteURL,$slashPositions,0);
137 | $this->assertEquals("http://example.com/a/b/myotherpage.html",$result["haystack"]);
138 | $this->assertEquals(11,$result["adjustment"]);
139 | $link = "../../../../../myotherpage.html";
140 | $result = linkStartsWithDDS($link,0,$absoluteURL,$slashPositions,0);
141 | $this->assertEquals("http://example.com/a/myotherpage.html",$result["haystack"]);
142 | $this->assertEquals(6,$result["adjustment"]);
143 | $link = "../../../../../../myotherpage.html";
144 | $result = linkStartsWithDDS($link,0,$absoluteURL,$slashPositions,0);
145 | $this->assertEquals("http://example.com/myotherpage.html",$result["haystack"]);
146 | $this->assertEquals(1,$result["adjustment"]);
147 | }
148 |
149 | public function testLinkStartWithDS(){
150 | $link = "./myotherpage.html";
151 | $theAbsoluteDirectory = "http://example.com/posts/";
152 | $result = linkStartsWithDS($link,0,$theAbsoluteDirectory,0);
153 | $this->assertEquals("http://example.com/posts/myotherpage.html",$result["haystack"]);
154 | $this->assertEquals(23,$result["adjustment"]);
155 | }
156 |
157 | public function testLinkStartWithDSsubdir(){
158 | $link = "./subdir/myotherpage.html";
159 | $theAbsoluteDirectory = "http://example.com/posts/";
160 | $result = linkStartsWithDS($link,0,$theAbsoluteDirectory,0);
161 | $this->assertEquals("http://example.com/posts/subdir/myotherpage.html",$result["haystack"]);
162 | $this->assertEquals(23,$result["adjustment"]);
163 | }
164 |
165 | public function testGetResourcePositions(){
166 | $haystackString = "This string does contain this link.";
167 | $matches = getResourcePositions($haystackString);
168 | $this->assertEquals(array(array("href='",33)),$matches);
169 | }
170 |
171 | public function testGetResourcePositionsNone(){
172 | $haystackString = "This string does not contain a link";
173 | $matches = getResourcePositions($haystackString);
174 | $this->assertEquals(array(),$matches);
175 | }
176 |
177 | public function testGetResourcePositionsCaseUppercase(){
178 | $haystackString = "This string does contain this link.";
179 | $matches = getResourcePositions($haystackString);
180 | $this->assertEquals(array(array("HREF='",33)),$matches);
181 | }
182 |
183 | public function testGetResourcePositionsCaseInsensitive(){
184 | $haystackString = "This string does contain this link.";
185 | $matches = getResourcePositions($haystackString);
186 | $this->assertEquals(array(array("HReF='",33)),$matches);
187 | }
188 |
189 | public function testGetResourcePositionsHref(){
190 | $haystackString = "This string does contain this link.";
191 | $matches = getResourcePositions($haystackString);
192 | $this->assertEquals(array(array("href='",33)),$matches);
193 | }
194 |
195 | public function testGetResourcePositionsSrc(){
196 | $haystackString = "This string does contain this link.";
197 | $matches = getResourcePositions($haystackString);
198 | $this->assertEquals(array(array("src='",33)),$matches);
199 | }
200 |
201 | public function testGetResourcePositionsWildCardSpaceBeforeEqual(){
202 | $haystackString = "This string does contain this link.";
203 | $matches = getResourcePositions($haystackString);
204 | $this->assertEquals(array(array("href ='",33)),$matches);
205 | }
206 |
207 | public function testGetResourcePositionsWildCardSpaceAfterEqual(){
208 | $haystackString = "This string does contain this link.";
209 | $matches = getResourcePositions($haystackString);
210 | $this->assertEquals(array(array("href= '",33)),$matches);
211 | }
212 |
213 | public function testGetResourcePositionsSingleQuote(){
214 | $haystackString = "This string does contain this link.";
215 | $matches = getResourcePositions($haystackString);
216 | $this->assertEquals(array(array("href='",33)),$matches);
217 | }
218 |
219 | public function testGetResourcePositionsDoubleQuote(){
220 | $haystackString = "This string does contain this link.";
221 | $matches = getResourcePositions($haystackString);
222 | $this->assertEquals(array(array("href=\"",33)),$matches);
223 | }
224 |
225 | public function testGetRootURL(){
226 | $absoluteURL = "http://example.com/posts/index.php";
227 | $result = getRootURL($absoluteURL);
228 | $this->assertEquals("http://example.com/",$result);
229 | }
230 |
231 | public function testgetCharacterPositionsCaseInsensitiveDefault(){
232 | $string = "Here Is a String that is case INsensitive";
233 | $positions = getCharacterPositions($string,"in");
234 | $this->assertEquals(array(13,30),$positions);
235 | }
236 |
237 | public function testgetCharacterPositionsCaseInsensitive(){
238 | $string = "Here Is a String that is case INsensitive";
239 | $positions = getCharacterPositions($string,"in",true);
240 | $this->assertEquals(array(13,30),$positions);
241 | }
242 |
243 | public function testgetCharacterPositionsNoResults(){
244 | $string = "Here Is a String that is case INsensitive";
245 | $positions = getCharacterPositions($string);
246 | $this->assertEquals(array(),$positions);
247 | }
248 |
249 | public function testgetCharacterPositionsCaseSensitive(){
250 | $string = "Here Is a String that is not case INsensitive";
251 | $positions = getCharacterPositions($string,"in",false);
252 | $this->assertEquals(array("13"),$positions);
253 | }
254 |
255 | public function testConvertRelativeToAbsolute(){
256 | $haystackString = "This string does contain this link. Here is another link.";
257 | $absoluteURL = "http://www.example.com/path/to/directory/index.html";
258 | $rootURL = "http://www.example.com/";
259 | $startingSlashMeansRoot = true;
260 | $result = convertRelativeToAbsolute($haystackString,$absoluteURL,$startingSlashMeansRoot,$rootURL);
261 | $this->assertEquals("This string does contain this link. Here is another link.", $result);
262 | }
263 | public function testConvertRelativeToAbsoluteNoRootPassed(){
264 | $haystackString = "This string does contain this link. Here is another link.";
265 | $absoluteURL = "http://www.example.com/path/to/directory/index.html";
266 | $startingSlashMeansRoot = true;
267 | $result = convertRelativeToAbsolute($haystackString,$absoluteURL,$startingSlashMeansRoot);
268 | $this->assertEquals("This string does contain this link. Here is another link.", $result);
269 | }
270 |
271 | public function testConvertRelativeToAbsoluteRootPassed(){
272 | $haystackString = "This string does contain this link. Here is another link.";
273 | $absoluteURL = "http://www.example.com/path/to/directory/index.html";
274 | $rootURL = "http://www.example.com/root/";
275 | $startingSlashMeansRoot = true;
276 | $result = convertRelativeToAbsolute($haystackString,$absoluteURL,$startingSlashMeansRoot,$rootURL);
277 | $this->assertEquals("This string does contain this link. Here is another link.", $result);
278 | }
279 |
280 | public function testConvertRelativeToAbsoluteSSIsRoot(){
281 | $haystackString = "This string does contain this link. Here is another link.";
282 | $absoluteURL = "http://www.example.com/path/to/directory/index.html";
283 | $rootURL = "http://www.example.com/root/";
284 | $startingSlashMeansRoot = true;
285 | $result = convertRelativeToAbsolute($haystackString,$absoluteURL,$startingSlashMeansRoot,$rootURL);
286 | $this->assertEquals("This string does contain this link. Here is another link.", $result);
287 | }
288 | public function testConvertRelativeToAbsoluteSSIsNotRoot(){
289 | $haystackString = "This string does contain this link. Here is another link.";
290 | $absoluteURL = "http://www.example.com/path/to/directory/index.html";
291 | $startingSlashMeansRoot = false;
292 | $result = convertRelativeToAbsolute($haystackString,$absoluteURL,$startingSlashMeansRoot);
293 | $this->assertEquals("This string does contain this link. Here is another link.", $result);
294 | }
295 | public function testConvertRelativeToAbsoluteTwoStartingSlashesString(){
296 | $haystackString = "This string does contain this link. Here is another link.";
297 | $absoluteURL = "http://www.youtube.com/path/to/directory/index.html";
298 | $startingSlashMeansRoot = false;
299 | $result = convertRelativeToAbsolute($haystackString,$absoluteURL,$startingSlashMeansRoot);
300 | $this->assertEquals("This string does contain this link. Here is another link.", $result);
301 | }
302 | public function testConvertRelativeToAbsoluteTwoStartingSlashes(){
303 | $haystackString = "link.";
304 | $absoluteURL = "http://www.youtube.com/path/to/directory/index.html";
305 | $startingSlashMeansRoot = false;
306 | $result = convertRelativeToAbsolute($haystackString,$absoluteURL,$startingSlashMeansRoot);
307 | $this->assertEquals("link.", $result);
308 | }
309 | public function testGetProtocol(){
310 | $this->assertEquals(getProtocol("http://www.google.com/"),"http://");
311 | $this->assertEquals(getProtocol("https://www.google.com/"),"https://");
312 | $this->assertEquals(getProtocol("ftp://www.google.com/"),"ftp://");
313 | }
314 |
315 | }
--------------------------------------------------------------------------------