Skip to content

Commit 3e5aa24

Browse files
committed
Merge branch '5.1'
2 parents 59c6679 + b237706 commit 3e5aa24

213 files changed

Lines changed: 18863 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
title: Quick Start Guide
3+
metadata:
4+
description: The official documentation for UserFrosting, a PHP framework and full-featured user management application.
5+
taxonomy:
6+
category: docs
7+
---
8+
9+
UserFrosting is a free, open-source jumping-off point for building user-centered web applications with PHP and Javascript. It comes with a sleek, modern interface, basic user account features, and an administrative user management system - all fully functioning out of the box.
10+
11+
[notice=note]This quick start guide is aimed at experienced PHP developers who already have a development environment set up. If that's not your case, head over to the [First Chapter](/background) to start your journey.[/notice]
12+
13+
[notice]This is the documentation for **UserFrosting 5**. If you are looking for documentation for _UserFrosting 4_, [click here](https://learn.userfrosting.com/4.6/).[/notice]
14+
15+
## Requirements
16+
17+
[notice=tip]Using Docker? [Check out the Docker Documentation](/installation/environment/docker) to install UserFrosting through it's native Docker integration.[/notice]
18+
19+
UserFrosting has a few system requirements. You need to make sure your local UserFrosting development environment meets the following requirements:
20+
21+
- PHP **8.1 or higher** (*8.3* recommended)
22+
- [Composer 2](https://getcomposer.org/)
23+
- [Node.js](https://nodejs.org/en/) **18.0** or higher, and [npm](https://www.npmjs.com) **9.0** or higher
24+
25+
## Installing UserFrosting
26+
27+
Use Composer to create an empty project with the latest version of UserFrosting skeleton into a new `UserFrosting` folder. This will clone the skeleton repository and run the installation process.
28+
29+
```bash
30+
composer create-project userfrosting/userfrosting UserFrosting "^5.1"
31+
```
32+
33+
[notice=tip]During installation, you can choose **sqlite** as database provider if you don't have a database provider available.[/notice]
34+
35+
If any dependencies are not met, an error will occur. Simply try again after fixing said error, or manually run `composer install` and `php bakery bake` from the install directory. For more information about the `bake` command, head to the [Bakery CLI](/cli) chapter.
36+
37+
At this point you can run locally using the PHP Server :
38+
39+
```bash
40+
cd UserFrosting
41+
```
42+
```bash
43+
php bakery serve
44+
```
45+
46+
You can now access UserFrosting at : [http://localhost:8080](http://localhost:8080)
47+
48+
## Visit your website
49+
50+
At this point, you should be able to access your application. You should see a basic page:
51+
52+
![Basic front page of a UserFrosting installation](/images/front-page.png)
53+
54+
## What's next...
55+
56+
For more detailed information about installing UserFrosting, or if you need help with the basic setup requirements, check out the [Installation Chapter](/installation). Otherwise, head over to the [Sprinkles Chapter](/sprinkles).
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
title: Introduction
3+
metadata:
4+
description: The PHP community has evolved considerably over the past decade, and this breakneck pace has caused a lot of people to get left behind. UserFrosting aims to help new and legacy developers navigate the overwhelming ocean of tools, packages, and concepts in PHP and the modern web development community as a whole.
5+
taxonomy:
6+
category: docs
7+
---
8+
9+
## Motivation
10+
11+
The PHP community has evolved considerably over the past decade, beginning with PHP5's support for object-oriented programming in 2006, to the first meetings of [PHP-FIG](http://www.php-fig.org/) to develop a [set of standards for PHP code](http://www.phptherightway.com/#code_style_guide), to the release of Composer as the _de facto_ package manager in 2012. At the same time the web development community as a whole has been changing, with websites becoming more dependent on Javascript and CSS to provide sophisticated client-side features. And Javascript has moved even faster!
12+
13+
This breakneck pace has caused a lot of people to get left behind. For someone who hasn't been doing web development continuously for the past ten years, it can feel like a hopeless task to try and get acquainted with all of the new tools and frameworks that seem to be coming out every day. Relevant comic from [Abstruse Goose](http://abstrusegoose.com/503):
14+
15+
![BlooP and FlooP and GlooP](/images/theoretical_mathematics_however_never_goes_out_of_fashion.png?resize=500)
16+
17+
The problem is that when you're a busy developer with a lot of Real-Life (tm) projects to work on, it's very difficult to set aside time to read a book about technology X - especially when you're not even sure that you really _need_ to learn X!
18+
19+
UserFrosting has a better idea. Instead of learning about these technologies as a purely academic exercise, you'll work on one of _your_ projects, and learn what you need as you go!
20+
21+
## What exactly will I learn?
22+
23+
There are three main categories that UserFrosting attempts to cover: software architecture, tools of the trade, and best practices. Most of the PHP developers we see in chat or on Stack Overflow are behind in at least one these areas:
24+
25+
### Software architecture
26+
27+
- Object-oriented programming and SOLID
28+
- The model-view-controller (MVC) paradigm
29+
- Designing for maintainability and reuse
30+
- Representational State Transfer (REST)
31+
- Security
32+
33+
### Tools of the trade
34+
35+
- Frameworks
36+
- Version control (Git)
37+
- Package management (Composer)
38+
- Templating engines (Twig)
39+
- Data modeling and database abstraction (Eloquent)
40+
- Logging
41+
- Markdown
42+
43+
### Best practices
44+
45+
- Coding style and standards
46+
- Development environments
47+
- Debugging
48+
- Test-driven development
49+
- Deployment strategies ("going live")
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
---
2+
title: The Client-Server Conversation
3+
metadata:
4+
description: Many developers do not really understand the basics of how HTTP and web applications work. This discussion attempts to clarify some common misconceptions.
5+
taxonomy:
6+
category: docs
7+
---
8+
9+
One of the most common misconceptions is that web applications are coherent pieces of software that sit on a server somewhere, and that the client "runs" this application in their browser. This is actually an illusion, carefully crafted to provide a smooth experience for the end user.
10+
11+
In reality, web applications are *conversations* between two agents with very poor memory - the **server**, and the **client** - which may be a web browser, mobile app, or another application. In modern web applications both the client *and* the server are typically going to need to run some code throughout their conversation. What's more, in the case of a PHP application, the client and server don't even speak the same language! The server runs only PHP, while the client runs only Javascript. (Note that there *are* server-side Javascript stacks, but we do not use them.)
12+
13+
## Server-side versus client-side code
14+
15+
Beginning developers are often confused by this, and you see questions on Stack Overflow like "how do I get my PHP in my Javascript" or "how do I keep the user from downloading the PHP and seeing my API keys?" These questions come from a misconception that users are actually *downloading* PHP files and then somehow running the scripts in their browser. This misconception is exacerbated by the way that web servers like Apache, by default, use the name and relative path of a PHP script as the URL required to run that script. Thus, it's easy to conclude that visiting **http://owlfancy.com/admin/login.php** is causing your browser to download **login.php** and run the script in that file. But this is not the case!
16+
17+
### Server-side code
18+
19+
What actually happens is that users, through their browsers (clients), make a **request** to the **web server** for a **resource**. This is usually done via a Uniform **Resource** Locator, better known as a URL. The web server generates a **response** to the request, and in the case of image, Javascript, CSS, and other static resources, it often does simply return the contents of the corresponding file. But when the client requests a resource that is mapped to a PHP script, the web server doesn't return the contents of the script. Instead, it *executes* the script on the server and returns the *output* of that script.
20+
21+
In the case of a web page, the output is usually an HTML document. However, a server-side script could produce JSON, XML, Javascript, CSS, or even dynamically generated images as its response. What's important is that the actual code of the script is never sent to the client - if it were, this could open all sorts of security risks!
22+
23+
### Client-side code
24+
25+
There are cases when the server *does* need to send code back to the client. For example, we might want to allow the client to automatically check if the information filled into a form is syntactically valid, without having to submit another request to the server. For this to work, we need a language that is universally understood by all types of browsers and clients. Luckily for us, such a language exists - it's called Javascript.
26+
27+
When you visit any modern web page, you first get the page itself (usually an HTML document), but then it contains a bunch of references to images, Javascript files, CSS files, and all sorts of other resources that are meant to enhance your experience of the page. Your browser is smart enough to see those references, and automatically request those resources as well. Then when it's finished grabbing a resource, it takes some action - displaying an image on the page, running some Javascript code, or modifying the styles of elements on the page.
28+
29+
Thus, to answer the questions from earlier:
30+
31+
> How do I keep the user from downloading the PHP and seeing my API keys?
32+
33+
You don't need to do anything. Your web server is configured to do this automatically. As long as you haven't changed the default behavior of your server in some bizarre way, the actual PHP code will *never* be sent back to the client. Only the *output* of the code is sent in the response.
34+
35+
> How do I get PHP in my Javascript?
36+
37+
Again, clients can't run PHP in their browsers. If you want to pass along the values of some PHP variables to the Javascript you send back to the client, you need to explicitly *generate* Javascript variables using PHP. For example:
38+
39+
```html
40+
<?php
41+
42+
// This is a PHP variable - (note the leading $)
43+
$baseUrl = "https://owlfancy.com";
44+
45+
?>
46+
47+
<button id="updateButton" type="button">Update My Owl</button>
48+
49+
<script>
50+
// This is a Javascript variable - (note no leading $)
51+
let baseUrl = <?php echo $baseUrl; ?> ;
52+
53+
// Our Javascript code can now reference the Javascript variable baseUrl
54+
$("#updateButton").on("click", function () {
55+
$("#myOwlLink").prop("attr", baseUrl + "/great-horned-owl");
56+
});
57+
</script>
58+
```
59+
60+
UserFrosting has a cleaner way of doing this using the Twig templating engine, but the principle is still the same.
61+
62+
For more complex PHP code that needs to be run in the middle of a block of Javascript code (for example, querying the database, which can *only* be done server-side), we'll need a way to let Javascript code ask the server to run some code on its behalf. Remember, the only way we can run code on the server is by making requests and then waiting for a response!
63+
64+
Fortunately, modern browsers support something called AJAX, which allows Javascript code to automatically make requests to the server. Thus, you might see something like:
65+
66+
```php
67+
<?php
68+
$baseUrl = "https://owlfancy.com";
69+
$owlId = getUserOwlId();
70+
?>
71+
72+
<button id="seeVoleHuntResults" type="button">See Vole Hunt Results</button>
73+
74+
<script>
75+
let baseUrl = "<?php echo $baseUrl; ?>";
76+
let owlId = "<?php echo $owlId; ?>";
77+
78+
$("#seeVoleHuntResults").on("click", function () {
79+
// This is a jQuery AJAX function that generates another request to the server!
80+
$.getJSON(baseUrl + "/vole-hunt/today",
81+
{
82+
"owl_id": owlId
83+
}).done(function(data) {
84+
// This is what the browser does when the request is complete successfuly.
85+
alert(data['voles_caught']);
86+
});
87+
});
88+
</script>
89+
```
90+
91+
### The Big Picture
92+
93+
Let's take a step back and talk about what's really going on here.
94+
95+
*The client's browser...*
96+
97+
*requests a dynamically generated resource from the server...*
98+
99+
*which contains some HTML and Javascript...*
100+
101+
*that Javascript contains instructions for the user's browser...*
102+
103+
*one of which is to automatically ask the server for some JSON data whenever the user presses a certain button...*
104+
105+
*the browser waits until the user actually presses that button to make the request...*
106+
107+
*and then the browser displays the result that it got from the server's response.*
108+
109+
This convoluted process is what ends up confusing a lot of new web developers, even those with significant programming experience in other domains.
110+
111+
## Example Web Application Conversation
112+
113+
It might be easier to understand this whole process if we provide an example of a web application as a "conversation" between your browser and a webserver. Suppose you type (or click a link from Google for) **http://www.owlfancy.com/health**. Your browser starts by reaching out to the server **owlfancy.com**, introducing itself, and making a request:
114+
115+
**Your browser:** "Hi, my name is 74.125.70.102. I'm a Chrome browser, version 53.0.2785.116, running on MacOS, and blah blah blah (insert a bunch of other stuff about me). Can I please have whatever's at *http://www.owlfancy.com/health*?"
116+
117+
**owlfancy.com:** "Sure. Looks like for that resource, I'm supposed to run this bit of code over here. Let's see what happens when I do that...Ok, it's done! Looks like it returned some HTML. Here you go. The status code is 200. Let me know if you need anything else. Bye!"
118+
119+
**Your browser:** "Hmm, according to this, I'm supposed to ask you for *jquery.js*, *bootstrap.js*, *pellet.js*, *bootstrap.css*, and something called */images/preening.jpg*. Can I have those as well please? I'm also supposed to get *https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic*, but that's not your problem. I can ask *fonts.googleapis.com* myself.
120+
121+
**owlfancy.com: (for each requested item):** "Sure, here you go. Let me know if you need anything else. Bye!"
122+
123+
**Your browser:** "Ok, now I'll run all this CSS and Javascript code." *Runs jquery.js, bootstrap.js, and pellet.js*
124+
125+
**Your browser:** "Hmm, looks like I'm supposed to give these boxes over here a border and shadow, change the font for this to Lora, and set it up so that when someone clicks "Forage", a picture of an owl swoops across the screen. Oh, it also wants me to tell Google Analytics and Facebook what I just did. Sure, after all my owner didn't tell me *not* to do that...I'll just send that information right now.
126+
127+
**Your browser:** "La la, waiting for my user to do something..."
128+
129+
***User clicks "Forage"***
130+
131+
**Your browser:** "Hey, someone just clicked 'Forage' - I'm supposed to do something now! Let's see. First I need to get a picture of an owl...excuse me, owlfancy.com? Can I have *http://www.owlfancy.com/images/swoop.jpg*?"
132+
133+
**owlfancy.com:** "Sure, just a second. Here you go! (Hands your browser an image file) The status code is 200. Let me know if you need anything else. Bye!"
134+
135+
**Your browser:** "Thanks! I'll just put this picture right here and then make it swoop across the screen. Wow!"
136+
137+
**Your browser:** "La la, waiting for my user to do something else..."
138+
139+
***User clicks "Account"***
140+
141+
**Your browser:** "Oh hi, owlfancy.com? Can I have whatever's at *https://www.owlfancy.com/account*?"
142+
143+
**owlfancy.com:** "Uhh, who the heck are you? Go ask for *https://www.owlfancy.com/login* instead. The status code is 302. Let me know if you need anything else. Bye!"
144+
145+
**Your browser:** "Ok, may I please have *https://www.owlfancy.com/login* then?"
146+
147+
**owlfancy.com:** "Sure, have some HTML and some more Javascript. The status code is 200. Let me know if you need anything else. Bye!"
148+
149+
**Your browser:** "I'll just show this to the user. Hmm, looks like a form of some kind. When they click 'Submit', I'm supposed to take whatever they put in this form and POST it to *https://www.owlfancy.com/login*. Good thing they're using HTTPS, or someone else on my network might see my user's password!"
150+
151+
***User types in 'VoleALaMode' for their username, and 'hunter2' for their password.***
152+
153+
***User presses 'submit'.***
154+
155+
**Your browser:** "Excuse me, owlfancy.com? I have something addressed for *https://www.owlfancy.com/login*. It says 'username: VoleALaMode, password: hunter2'.
156+
157+
**owlfancy.com:** "Sure thing, I'll see if I can find that user... (checks the database) Sorry, I didn't find anything for that combination of username and password! Here, have an error message: 'Your username or password is invalid.' The status code is 400. Let me know if you need anything else. Bye!"
158+
159+
**Your browser:** "Well that didn't go well. I guess I'd better break the news to my user. Hmm, according to the Javascript on this page, I'm supposed to show the user this error message in this box over here. I'll just go ahead and do that."
160+
161+
**Your browser:** "La la, waiting for my user to do something else..."
162+
163+
***User changes the username to 'VolesALaMode' and presses submit again***
164+
165+
**Your browser:** "Excuse me, owlfancy.com? I have something addressed for *https://www.owlfancy.com/login*. It says 'username: VolesALaMode, password: hunter2'.
166+
167+
**owlfancy.com:** "Sure thing, I'll see if I can find that user... (checks the database) Found her! Here, have a success message: 'Welcome back, VolesALaMode!' Also, take this special code: 'nabddsXGa4FK0JHCipeEnAVXy8'. Just show this to me with any other requests you make, and I'll know who you are. The status code is 302. You should probably ask me for *https://www.owlfancy.com/account* next. Let me know if you need anything else. Bye!"
168+
169+
**Your browser:** "Special code, eh? I'll just add this to my cookies for this site and send it back with any more requests I end up making. I'm sure that's what she wants me to do! Ok, now I'm supposed to ask for *https://www.owlfancy.com/account*..."
170+
171+
**Your browser:** "Excuse me, owlfancy.com? Can I have *https://www.owlfancy.com/account*? I also have this special code. It's 'nabddsXGa4FK0JHCipeEnAVXy8'."
172+
173+
**owlfancy.com:** "Sure thing. Let me see if I recognize that special code...hey, I know you, you're VolesALaMode! (erm, at least I hope it's you and not someone who stole your code!) Let me go look up a few things for you... Hmm, I'm supposed to get a list of your next HootMeets from the database, whatever a HootMeet is...ok, found it. I'll just lay them out in this nice HTML template and send it back. Here, have this HTML! The status code is 200. Let me know if you need anything else. Bye!"
174+
175+
**Your browser:** "Thanks! I'll just show my user this..."
176+
177+
***Browser now shows https://www.owlfancy.com/account***
178+
179+
**Your browser:** "There's some Javascript here too, so I'll just run that. Hmm, it's telling me that I should ask for *https://www.owlfancy.com/account/notifications*. Hi owlfancy.com, can I have that please? I also have this special code. It's 'nabddsXGa4FK0JHCipeEnAVXy8'."
180+
181+
**owlfancy.com:** "Sure thing. Hey, I know you, you're VolesALaMode! Here you go, have some JSON. The status code is 200. Let me know if you need anything else. Bye!"
182+
183+
**Your browser:** "Ok, what am I supposed to do with this? I'll just look back to the Javascript for this page. Let's see, it wants me to display these notifications with a green background and a light shadow over here, just below the navigation bar. Can do!"

0 commit comments

Comments
 (0)