Jump to content

Is ProcessWire right here?


Thor
 Share

Recommended Posts

Hi, beloved ones. Sorry if my intro post is a bit long but like most of those that were new once, I assume you had questions. I knew ProcessWire from some years back, never used it before and I used mostly ExpressionEngine for sites, as well just custom PHP/MySQL for other things as well other stuff with Smarty and other CMS. So it was mainly CMS for site parts and for other more fancy things, just PHP.

Recently a new project landed on my feet, and I was struggling just to pick and learn a framework or go plain vanilla PHP. The obvious choice was CodeIgniter, CakePHP and maybe Laravel, but I was inclined to CakePHP when I decided to dig a bit more. For some strange reason, I landed again on ProcessWire and more than one here claimed its more like a framework than a CMS, so you can build as many custom things as you want. And decided to finally give it a go instead of trying to learn something completely new. Installed in a few minutes, and then in the past 2-3 days I was reading and learning a bit. Boy, I love it. No boxed CMS or forcing me to stick to a specific convention, and I can code straight PHP code without any particular needs or requirements, not to mention use my own files like CSS, JS and mix code with Processwire. It just works! I assume this is really the best tool for those doing PHP things that need a bit of help from a framework or just a software like PW that can speed up things.

I finally decided that instead of trying to do everything from scratch in PHP I would pick up Processwire for several reasons. Authentication and permissions system build (why re-invent the wheel), cache and many other features, like plugins and other things I could need in the future, not to mention an amazing community it seems.

So here come my questions....

My project consists of a web app, not a content site. More an interface where users need to log in and manage their own unique data which I also need to pull out using other databases and API's. So this is already different to what most people probably build here in terms of sites. 

Now don’t get me wrong. I don’t expect ProcessWire to do everything and my idea was to just use ProcessWire for he GUI part to simplify things and stick to my own code and database for more complex tasks. But then reading the forums and looking at what some people are doing it seems why would I even do this? It seems if I’m not mistaken that every data in ProcessWire is a database field (I checked and it seems everything is saved to the DB) and people are using it to store users data and process them after that. So my question is should I maybe stick to using ProcessWire for most things or still go with a mixed route, GUI processWire mixed with my own modules and codes?

The first thing that came to my mind was if I am going with separate/split databases or just use the same ProcessWire database and build extra tables for my data. For security and stability reasons, the obvious choice is to split databases, but then again, I could always do the sharding in the future if I need and just use for now (for simplicity reasons) the same MySQL database that processwire is using but my own custom tables. But then after digging more, it seems maybe not even that is required as ProcessWire is able to store users data by nature. I’m not sure and still a bit confused about but Im not mistaken it would not be complicated to store users data with specific formats in the database. The other reason I want ProcessWire is security. I really don't want ot be having to do all the sanitization and SQL inyection protection or have some forms badly build by myself and have a security hole. I guess like with other systems, ProcessWire can do all the XSS, SQL protection, etc. out of the box.

Is ProcessWire the right tool for this? Storing users accounts data, which they can retrieve in the GUI or I can tap into the database to use for other purposes? Or should I just stick to using my own tables/DB and access and manipulate that data with my own PHP code build in PW templates?

So far this is where I got so far in a few hours:"

Installation.

Locked everything requiring a login.

Investigating how the user/roles/permissions works.

I didn't tested anything related fields, or storing/retriving users data yet.

For my surprise when I looked the database, I could not find a users table either. I'm not sure how I'm supposed to identify or access users data, while the test users I created have an ID which I can pull out, this seems randomly created by ProcessWire. I would need to identify specific users, so data can be unique to them, and then make granular permissions for those users to what they can or can't access based on this data. Thing a control panel or admin panel type of site.

Link to comment
Share on other sites

I'm using pw for a web app as well. I'm not PHP expert just a self-taught programmer learn from copy and paste :) What I did wrong for the first dev with pw I was not using pencil and paper to design the process first ...

So just for sharing to your question:

Page in PW is not just a content; I use PW front-end as a database form to process certain action. 

Each process will refer to the user's role

Create the template to accommodate that process and setup user's access right for each template. No need to create a file template if it's not a content template.

Finally, configure the access right on the field level. But be careful here, to write down in detail in your documentation, or just use hook for that purpose.

  • Like 1
Link to comment
Share on other sites

Great to hear that I was not the only one thinking of using it for web apps instead of just blogs, content or community sites (but if you think about it, those sites are also simple web apps :) ). 

So what you are saying is that you did not create a separate database or tables and are using PW as a database storage and as well front end? That is the part I'm a bit confused. Are pages used as data tables here? How do you relate a table to a user?

With PHP I would just relate it to the user id that is logged. Example:

Get X data from Table A for user ID 50

How secure and efficient is this with ProcessWire? I don't plan to create something big, I'm sure that would be a disaster in terms of slow SQL queries (in particular if PW is storing everything into the DB) and I'm sure that creating a particular DB schema would be far more efficient, but I'm curious for simple stuff how people are doing this. They create a page, assign fields to it, put in a group, restrict users to a group. But how do you avoid other users pulling out data that does not belong to them?

I'm not a programmer in any way either. More a web developer&system/network admin. Sure, I can code, and I coded things before and I also have a fancy PHP IDE, but just like you I do most things using examples and Googling alot. And while I'm impressed on how I managed to create fairly complex stuff in the past, I take forever even for basic stuff. One reason to pick ProcessWire, I did not manage to understand frameworks in the day I tried but after reading a bit of tutorial's and stuff on ProcessWire it's starting to make sense. Sure, I can't still think of things in my head, the reason why I ask. I guess every system has a learning curve. Once you are into that curve, things start to flow once you see the magic, but getting on board is the tricky part and I think most people give up on that part. Having knowledge of code in my case of course helps but I still don't understand how ProcessWire works when it comes to storing users data or manipulating it, and then storing it back.

Link to comment
Share on other sites

20 minutes ago, Thor said:

The concept of using pages as data holders seems strange

This is just terminology, do not meditate too much on it ;) eg.: WordPress: custom post types, Drupal: node. Surely, there are more like these out there... Each must have its history behind it.

  • Like 1
Link to comment
Share on other sites

1 hour ago, Thor said:

So what you are saying is that you did not create a separate database or tables and are using PW as a database storage and as well front end? That is the part I'm a bit confused. Are pages used as data tables here? How do you relate a table to a user?

With PHP I would just relate it to the user id that is logged. Example:

Get X data from Table A for user ID 50

How secure and efficient is this with ProcessWire? I don't plan to create something big, I'm sure that would be a disaster in terms of slow SQL queries (in particular if PW is storing everything into the DB) and I'm sure that creating a particular DB schema would be far more efficient, but I'm curious for simple stuff how people are doing this. They create a page, assign fields to it, put in a group, restrict users to a group. But how do you avoid other users pulling out data that does not belong to them?

 

On each process page I usually added an option field for i.e named it as 'toggles' to restrict user's view access. So in wire('pages')->find('template=your_template, toggles=your_user_roles'), you can restrict the user's access.

At the moment I'm developing the process for thousands of property addresses and contractors, the queries are quite fast. It always relies on how you design the process itself.

In term of security, at least until today pw doesn't have any security issue. As long as you're sure to manage your front-end script carefully I think pw core is really good in the security part.

Link to comment
Share on other sites

Well, I was not referring to the security of ProcessWire itself as the core, but the end user result. (create by me, you, or others with PW).

Example, you create a nice GUI/web/frontend for your web users, and with all the beautiful entry and data but your form, the way you are saving data into the system has a big SQL injection problem, or the way its retrieving data also poses a problem. I'm not sure if the software does this, our you still need to sanitize all input saved correctly. If you think about it, every data is still saved into the MySQL database, which means the data has to be checked somehow to make sure it's the right data that is saved. In the case of getting data or queries, you need to make sure it's only for that particular authorized person and not someone else.

I searched but I was not able to find if ProcessWire supports regex checking or validation on fields. In my case, I need to add things a bit more complicated that just words or numbers, but make sure they have the proper format when saved, so regex is mostly the only way to do it correctly. If there are fields that can have regex validation, that would be amazing. Otherwise, I will have to create my own PHP fields/forms which means most of the work would be done outside of PW.

As for the roles/permissions you posted, that seems to restrict users groups/permission to a page if I'm not mistaken. I found out how to do this with templates, groups and assigning users to that group only. It seems this can also be done with fields and that would solve that issue but I was referring to users unique data (that belongs only to that one user and nobody else). Think of it like a profile page, where users update their password or avatar.

So users "Joe" is logged to a template page called "Profile". I want Joe to save his home address here and avatar. (Or I want to save it directly to the DB and Joe can retrieve this when he access that page), then Joe can access a page and check his address, avatar. Now you don't want user "Mike" to access the same template and see Joe's address or be able to modify his avatar. That is the part I was asking. How do you related data to a particular user only?

Link to comment
Share on other sites

37 minutes ago, Thor said:

So users "Joe" is logged to a template page called "Profile". I want Joe to save his home address here and avatar. (Or I want to save it directly to the DB and Joe can retrieve this when he access that page), then Joe can access a page and check his address, avatar. Now you don't want user "Mike" to access the same template and see Joe's address or be able to modify his avatar. That is the part I was asking. How do you related data to a particular user only?

https://processwire.com/api/ref/user/

Link to comment
Share on other sites

@Thor Don't know how you came to that conclusion.

You said you want to have a profile page for users to see and edit their information. So you make that page accessible only to logged in users, once a user is logged in he sees his information. That information comes from the $user variable that holds the data of the logged in user ($user->name, $user->email, $user->your_custom_field etc).

If you want users to see other users profiles you can do that too. You can enable url segments and the url segment is the username. Then in your template you get the information of an user like this:

// don't use $user or you'll overwrite the PW $user variable
$u = $pages->get("template=user, name={$input->urlSegment1}");
// or
$u = $users->get($input->urlSegment1);
// and get info about the user
$u->name;
$u->email;
// change user info
$u->of(false); // http://cheatsheet.processwire.com/page/built-in-methods-reference/page-setoutputformatting-true-false/
$u->name = "whatever";
$u->save();

 

Link to comment
Share on other sites

5 minutes ago, fbg13 said:

@Thor Don't know how you came to that conclusion.

You said you want to have a profile page for users to see and edit their information. So you make that page accessible only to logged in users, once a user is logged in he sees his information. That information comes from the $user variable that holds the data of the logged in user ($user->name, $user->email, $user->your_custom_field etc).

If you want users to see other users profiles you can do that too. You can enable url segments and the url segment is the username. Then in your template you get the information of an user like this:


// don't use $user or you'll overwrite the PW $user variable
$u = $pages->get("template=user, name={$input->urlSegment1}");
// or
$u = $users->get($input->urlSegment1);
// and get info about the user
$u->name;
$u->email;
// change user info
$u->of(false); // http://cheatsheet.processwire.com/page/built-in-methods-reference/page-setoutputformatting-true-false/
$u->name = "whatever";
$u->save();

 

So the $user variable tells PW that piece of the data belongs only to that user forcing only that user (besides admin) to be able to retrieve it?

What you mentioned is exactly what I want to avoid. Example, using page ID for each user, I don't want someone loading the ID of another user and pulling out his data. Assuming you use pages to store users data like /profile/user/1, /profile/user/2.

Do I make sense? Sorry but I don't know PW enough. Yet...

Link to comment
Share on other sites

32 minutes ago, fbg13 said:

the $user variable that holds the data of the logged in user

It's not the logged in user but the current user, if user is not logged in then it represents the guest user.

@Thor Say the profile page has only the code below.

// if user in not logged in redirect to login page
if(!$user->isLoggedin()) {
    // redirect code
}
echo $user->name;

If you visit the page, just /profile/ (no user id, no user name), it shows your name, if another user visits the page he sees his name, not yours.

  • Like 1
Link to comment
Share on other sites

I already know that. But the profile was just an example I made. I'm not actually asking here for the profile data of a user, but any data. This means any custom data and fields I create, or the user submits, if that will be unique to that user only or it will be just general data.

Link to comment
Share on other sites

8 minutes ago, Thor said:

I already know that. But the profile was just an example I made. I'm not actually asking here for the profile data of a user, but any data. This means any custom data and fields I create, or the user submits, if that will be unique to that user only or it will be just general data.

The answer is; It depends. :)

ProcessWire permissions are Field/Template specific. Out of the box, you can define which roles/permissions apply to any field or template (see Access tab). When you create a field and assign it to a template, its 'data' is subject to the access control you defined, or it's parent, if none is defined. Ryan wrote another module to expand on this functionality here. Also, you can test the author id of a page whether it matches the current user in order to limit access. The thing I have learned in my short time working with ProcessWire is that there are many ways to accomplish what you want. But that is the second edge of that sword in trying to decide the best approach for your needs. So the bottom line is, if you want some data to be restricted, then you restrict access. That isn't meant to be a flippant answer, rather to show that you can make things as simple or complex as needed. ProcessWire doesn't limit you.

BTW, welcome to the forums!

  • Like 2
Link to comment
Share on other sites

Link to comment
Share on other sites

12 hours ago, rick said:

The answer is; It depends. :)

ProcessWire permissions are Field/Template specific. Out of the box, you can define which roles/permissions apply to any field or template (see Access tab). When you create a field and assign it to a template, its 'data' is subject to the access control you defined, or it's parent, if none is defined. Ryan wrote another module to expand on this functionality here. Also, you can test the author id of a page whether it matches the current user in order to limit access. The thing I have learned in my short time working with ProcessWire is that there are many ways to accomplish what you want. But that is the second edge of that sword in trying to decide the best approach for your needs. So the bottom line is, if you want some data to be restricted, then you restrict access. That isn't meant to be a flippant answer, rather to show that you can make things as simple or complex as needed. ProcessWire doesn't limit you.

BTW, welcome to the forums!

Thank you, Rick, this seems to be the clearest response so far.

So matching the author ID to the page is one way? I will research that. Thanks.

That is what I was asking. Let me clarify for everyone; I know how the page/role permission works but the last granular way is per user data.

So, the guest has Read access to everything. Home has to be accessible, I redirected home to a login and used an include for all other templates, so they require login. So no pages can be accessed by guest now. Done.

And I restricted some pages per roles, assigning test users to those roles. Also done.

But Roles gives access to all users assigned to that role. That was also clear from the beginning, but the last step higher permission system is PER user data. This means that even users in the same role, and accessing the same page and same fields, can only get data that belongs to them. I think some are just creating unique pages for each user, but even so, you need to have some code somewhere (if PW does not do this by default) to make sure only that user can load his content. Otherwise, someone that also has that role can load the page manually.

To clarify, I was asking if PW had a build in feature to link submitted data only to the user sending the data, or this has to be coded somehow or used with a module?

I imagine this is something built in, but I could be wrong. Something that checks the user ID and then links all submitted data for those fields only to that user ID.

So the $author seems one way to do it. Any other way?

Should I also be looking at this?

http://modules.processwire.com/modules/page-edit-field-permission/

Link to comment
Share on other sites

Hi @Thor

What I said about the author may not be the actual name. I think it is $page->createdUser, which indicates the user (author) that created that page. Sorry for my broad terminology.

And Yes, page edit field permission module is a finer control over access.

7 minutes ago, Thor said:

To clarify, I was asking if PW had a build in feature to link submitted data only to the user sending the data, or this has to be coded somehow or used with a module?

When you say 'submitted data' that implies a form action, either front-end or admin, so yes, you will need to code for your specific conditions. For example, User-A submits whatever through your front-end form. Your code will need to sanitize that form data, then save that data to the desired page. After you process the form data, and before you save the data, you can specify other properties, such as created user, or whatever fields you defined for that template. Later, you can retrieve one or more pages that the user created, or has access to, or however you define it, for whatever purpose you intend. That means User-B won't see what User-A has done. You could also retrieve all pages, regardless of user, to display to any user if you desire. Take the case of a user profile. ProcessWire, by default, only shows the profile data to the current user, and not another user. But it doesn't prevent you from retrieving all user profiles and displaying a list to any user if that is what you want to do. 

As I re-read your initial post, it is clear that you do your research. What you are asking for your project is very doable in ProcessWire. Even if you find you need to create custom tables, ProcessWire makes that very easy to do -- see the wire database pdo. There is a ton of information in this forum as well as the normal API reference, captain hook, etc.

Should you have any questions during your development, there are many far more talented members here that will be glad to jump in and help out.

  • Like 2
Link to comment
Share on other sites

Thanks, I also found this:

It seems from reading what most people do is actually create a unique page for each user and restrict it to that user only. Sounds a bit messy but maybe that is the way to go. I will try to find some tutorial or example for users submitted data, as most are just very general explaining how PW works, and how the role, permissions work but for all users. None is actually talking about protecting users submitted data from other users in PW (excluding admins of course...). Sanitization is something I'm aware. I will add some data myself and some data will be added by users. The only concern I have is to make sure that one user is not able to hack or manipulate the system and try to access data from another user.

Link to comment
Share on other sites

User submitted data is nothing more than a group of fields that define the type of data you want to save, such as text (user name), images (avatar), etc. Those fields are then assigned to a template, which is nothing more than a grouping definition for those fields, eg, user name, address, etc. That template is then assigned to a page, which is basically the interface between the user and the database. You code how you want the user data entry form to appear, assign each data element to the appropriate field, then save the page. You use the current user (the one logged in) to determine which page to display. For example, $pages->get("page->createdUser = $user->id") returns an array of pages that $user created. No other user will see it, nor can they hack it. Your code determines what is accessible. You can define additional permissions using those modules mentioned earlier to further restrict what any particular user may do or not do. For example, if ( $user->hasPermission('whatever') ) { do something }.

  • Like 2
Link to comment
Share on other sites

Ok, it seems PW does indeed relate data only to the logged user. So my main question here is solved. I tested this several times now, and it works as expected. :-[

Example, I can get my user data field and with this code it will restrict only to the particular user logged in:

$planet = $user->my_planet;
echo $planet;

Perfect :rolleyes:

But for the hell of me, I have tried every possible combination for 1 hour now, and I cannot find how to do the reserve. Save data !!! >:D

This does not work and I tried multiple combinations now or 10 or 20 different arrangements:

$user->my_planet = "mars";
$user->save('my_planet');
$user->save();

Or 

$value = "mars";
$page->my_planet->($value);
$page->save();

Why is it so hard to find this information? Everything I can find is related to people making forms or saving with forms and I just want something simple to test and learn. Not create a full form yet.

I want to understand how to save the data to a field when the user is logged on or at least manually specify the user (if I run as another user that needs to save data to another user). Then if it works, try with sanitization.

I have read the API and docs several times and not one single example. At least everything I try fails. No data is saved to my field when I run as the logged in user.

Link to comment
Share on other sites

Are you getting any error message? Can you try this and see if it works?

$user->of(false); // this disables output formatting
$user->my_planet = "mars";
$user->save('my_planet');

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...