# University of Washington CSE 190M

## Section 9: PHP Web Services and Scriptaculous

Except where otherwise noted, the contents of this document are Copyright 2012 Marty Stepp, Jessica Miller, and Victoria Kirst. All rights reserved. Any redistribution, reproduction, transmission, or storage of part or all of the contents in any form is prohibited without the author's expressed written permission.

# Exercise : Prime Factors (by Eli White)

Write a PHP web service, factors.php, which will return (in `text/plain`) the prime factors of a provided number. For example, the request `factors.php?n=264` would return:

``2 * 2 * 2 * 3 * 11``

You can make queries to the working solution to test. One simple algorithm for prime factorization of `num` is as follows:

```for fact from 2 to num:
while num % fact = 0:
num = num / fact
add fact to the list of prime factors of the original num
```

Make your web service return a `400 Invalid Request` HTTP error code with an instructive error message if the parameter `n` is not provided.

# Exercise Prime Factors

```<?php
if (!isset(\$_GET['n'])) {
print "Please provide a parameter n.";
} else {
\$factors = factorize(\$_GET["n"]);
print implode(" * ", \$factors);
}
function factorize(\$num) {
\$factors = array();
for (\$factor = 2; \$factor <= \$num; \$factor++) {
while (\$num % \$factor == 0) {
\$num /= \$factor;
array_push(\$factors, \$factor);
}
}
return \$factors;
}
?>```

# Exercise : Prime Factors 2 (by Roy McElmurry)

Modify your PHP web service, factors.php to return the prime factors of a provided number in JSON format. For example, the request `factors.php?n=264` would return:

``{"number": 264, "factors": [2, 2, 2, 3, 11]}``

You can try out the service here.

# Exercise Prime Factors 2

```header('Content-type: application/json');
if (!isset(\$_GET['n'])) {
print "Please provide a parameter n.";
} else {
\$n = \$_GET["n"];
\$ret = array(
"number" => \$n,
"factors" => factorize(\$n),
);
print json_encode(\$ret);
}```

# Exercise : Address Book (by Alex Miller)

You are given HTML and JS files for an address book web application. The javascript file sends requests to a web service that reads and saves address data. You can view the working application here. Write the PHP file, `addressbook.php`, that provides the following behavior:

• If a `GET` request is sent to `addressbook.php`, then print out, in plain text, a comma separated list of the names of people in the address book. If the `name` parameter is set, then print out the address associated with that name.
• If a `POST` request is sent to `addressbook.php`, then you must add a name/address pair to the address book's data. You may assume that the user is passing a `name` and `address` parameter. You will need to save the data in the address book in some way. You may choose the specific method.

Extra: Edit `addressbook.js` to add Scriptaculous effects to the page.

```header("Content-type: text/plain");
if (\$_SERVER['REQUEST_METHOD'] == "GET") {
\$lines = explode("\n", \$file_text);
if (isset(\$_GET["name"])) {
\$name = \$_REQUEST["name"];
foreach (\$lines as \$line) {
\$info = explode(",", \$line);
if (\$info[0] == \$name) {
print \$info[1];
}
}
} else {
\$names = array();
foreach (\$lines as \$line) {
\$info = explode(",", \$line);
array_push(\$names, \$info[0]);
}
print(implode(\$names, ","));
}
}
```

```if (\$_SERVER['REQUEST_METHOD'] == "POST") {
\$name = \$_REQUEST["name"];
\$file_text .= "\n" . \$name . "," . \$address;
}
```

# Exercise : Address Book 2 (by Roy McElmurry)

Modify your `addressbook.php` web service to return data in JSON format. You should use these HTML and JS files for this version.

For example, if a GET request is made without any parameters, you should return

``{"names": ["name1", "name2", ...]}``

And if a GET request is made with the `name` parameter, you should return

``{"name": "some_name", "address": "some_address"}``

You can try out the service here.

```header('Content-type: application/json');
if (isset(\$_GET["name"])) {
\$name = \$_REQUEST["name"];
\$ret = array("name" => \$name, "address" => "");
foreach (\$lines as \$line) {
\$info = explode(",", \$line);
if (\$info[0] == \$name) {
}
}
print json_encode(\$ret);
} else {
\$names = array();
foreach (\$lines as \$line) {
\$info = explode(",", \$line);
array_push(\$names, \$info[0]);
}
print json_encode(array("names" => \$names));
}```

# Exercise : Garbage Collector (by Morgan Doocy)

Write the necessary JavaScript / Scriptaculous code to complete the skeleton HTML and JS, which removes each icon with an `Effect.Puff` when it is dragged and dropped onto the trash can as in this working solution.

You will first need to inject 20 IE6 icons (imgs of class `.browser`, with a `src` of ie6.png) into the #browsers div. Use the provided `positionRandomly` function to give each img that you inject a random location.

# Exercise : Garbage Collector (by Morgan Doocy)

Refer to the Scriptaculous documentation for Draggables, Droppables, and Core Effects to figure out how to configure your objects so that:

• All IE6 icons are draggable.
• The trash icon is a Droppable that will "accept" only elements of class `.browser`.
• Dragging and dropping a `.browser` icon to any part of the page except the trash can results in the icon returning to its original position.
• Hovering any `.browser` element over the trash icon will cause its class to change to `.full`.
• IE6 icons will disappear in an `Effect.Puff` when they are dropped onto the trash icon.
• After the Puff effect has finished, the puffed icon should remove itself from the page.

# Exercise Garbage Collector

```document.observe('dom:loaded', function() {
createBrowsers();
accept: 'browser',
hoverclass: 'full',
onDrop: removeBrowser
});
});
function createBrowsers() {
for (var i = 0; i < 10; i++) {
var img = \$(document.createElement('img'));
img.src = 'http://webster.cs.washington.edu/cse190m/sections/9/trashcan/ie6.png';
positionRandomly(img);
new Draggable(img, {
revert: 'failure'
});
\$('browsers').appendChild(img);
}
}```

# Exercise Garbage Collector

```function removeBrowser(elem) {
new Effect.Puff(elem, {
duration: .5,
afterFinish: function() {
elem.remove();
}
});
}```

# Exercise : Photo Gallery (by Sylvia Tashev)

Write an animated photo gallery using Scriptaculous. Start with the skeleton HTML and JS. Click the image to run our sample solution: (solution JS code `gallery.js`):

Right now, when you double-click an image, it shows in the large `mainimage` area. But it's boring! Add Scriptaculous effects such as the following...

# Exercise : Photo Gallery

1. When the page first loads up, the thumbnail of the current `mainimage` image (the first one) should scale up to 200% of its normal size, and the `mainimage` image should have a visual effect, such as shaking.
2. When the user double-clicks a thumbnail to show a new image, the same effects as just described should occur. The new thumbnail should grow to 200% size, and the `mainimage` image should shake as it changes. Also the old selected thumbnail should shrink back to its previous size. Note that if you double-click on the same thumbnail twice in a row, it shouldn't break.
3. When the previous/next, left/right arrows are clicked, the corresponding previous or next image should be placed into the large area. It should be as though the user double-clicked on the previous or next thumbnail, complete with the same effects.

# Exercise : Photo Gallery

1. Make the list of images so that its order can be rearranged by dragging the images left and right. See the Scriptaculous wiki page for ideas and options such as `tag` and `constraint`.
2. Make it so that when the user drags a thumbnail image to the `mainimage` area, the large image will update. (This is the same behavior as when the thumbnail is double-clicked. See the Scriptaculous Wiki pages about dragging and dropping.
3. If you finish the previous effects, add other bling to the page. For example, when the images are rearranged by dragging them to sort them, make effects occur on the affected thumbnails. Or add sequences of effects that occur on the same element; for example, when the large `mainimage` is updated, make it have two effects in a row, such as highlighting and then shaking.

# Exercise Photo Gallery

You can view the solution javascript here.