sfDoctrineGuardPlugin relations with sfDoctrineApplyPlugin (delete and create users) - symfony-1.4

I use symfony 1.4.11. I use sfDoctrineGuardPlugin and sfDoctrineApplyPlugin.All works fine, but... In my backend I have user list, where I can manage users.When I create new user from backend, his profile create only in sf_guard_user table, or when I delete user from backend , it deleted his profile only from sf_guard_user table, , but it do not delete his profile from sf_guard_user_profile table...So how to fix it?Maybe I am made something wrong in cofiguration of both plugins? Thank you!
sfGuardUserProfile:
connection: doctrine
tableName: sf_guard_user_profile
columns:
id: { type: integer(4), primary: true, autoincrement: true }
user_id: { type: integer(4), notnull: true , primary: false }
salutation: { type: string(10), notnull: true }
first_name: { type: string(30), notnull: true }
last_name: { type: string(30), notnull: true }
country: { type: string(255), notnull: true }
postcode: { type: string(10) , notnull: true }
city: { type: string(255), notnull: true }
address: { type: string() , notnull: true }
phone: { type: string(50) }
email: { type: string(255), notnull: true }
validate: { type: string(17) }
banned: { type: boolean, default: 0 }
payed_until: { type: datetime, notnull: true}
relations:
User:
class: sfGuardUser
foreign: id
local: user_id
type: one
onDelete: cascade
foreignType: one
foreignAlias: Profile

Just change my database from MyISAM to INNODB and all works fine!

About creating new user - I'm not sure if there is such a feature in both plugins in the first place. (At least I don't know about it).
About deleting user and related data from sf_guard_user_profile table - I think that most likely there is some problem with relations definition. Check the sfDoctrineApplyPlugin readme again in the installation section where the sf_guard_user_profile table is defined. You need to have onDelete: cascade set for the User relation.
And at the end check if the proper sql was generated and applied to the database schema.
Regards.

Related

Meteor not able to create user after adding attaching schema to users collection

I have installed mizzao:user-status package to track user activity like online, idle status.
I have added status to users collection:
import SimpleSchema from "simpl-schema";
const userSchema = new SimpleSchema({
status: {
type: Object,
optional: true,
},
"status.lastlogin": {
type: Object,
optional: true,
},
"status.lastlogin.date": {
type: Date,
optional: true,
},
"status.lastlogin.ipAddr": {
type: String,
optional: true,
},
"status.userAgent": {
type: String,
optional: true,
},
"status.idle": {
type: Boolean,
optional: true,
},
"status.lastActivity": {
type: Date,
optional: true,
},
"status.online": {
type: Boolean,
optional: true,
},
});
Meteor.users.attachSchema(userSchema);
On sign up page I have createUser code:
Accounts.createUser(
{ username, email, password },
async (error) => {
if (error && error.reason) {
setErrors({ signUpFailed: error.reason });
setIsLoading(false);
return;
}
navigate('/dashboard', { replace: true });
}
);
Whenever I try to register I get an error on the server:
Exception while invoking method 'createUser' Error: After filtering out keys not in the schema, your object is now empty
All fields in status are set to optional yet I am still getting this error. If I remove Meteor.users.attachSchema(userSchema); then create user works.
The error is pretty clear. In short it went through your schema, removed things that are not in it and found that it leaves you with empty object. As such you need to define all the other fields that is being used on the users collection. There are two ways how to avoid this issue. First is not to set any schema on the users collection, second is to properly describe everything that is being set and stored there. If you are adjusting the the user documents, then the second approach is best. Bellow is mine description, which also includes definitions for alanning:roles for quick reference. You can find more details on collection2 documentation:
https://github.com/Meteor-Community-Packages/meteor-collection2#attach-a-schema-to-meteorusers
const userSchema = new SimpleSchema({
username: {
type: String,
// For accounts-password, either emails or username is required, but not both. It is OK to make this
// optional here because the accounts-password package does its own validation.
optional: true
},
emails: {
type: Array,
// For accounts-password, either emails or username is required, but not both. It is OK to make this
// optional here because the accounts-password package does its own validation.
optional: true
},
'emails.$': {
type: Object
},
'emails.$.address': {
type: String,
regEx: SimpleSchema.RegEx.Email,
optional: true
},
'emails.$.verified': {
type: Boolean,
optional: true
},
'emails.$.primary': {
type: Boolean,
optional: true
},
createdAt: {
type: Date
},
profile: {
type: Object,
optional: true,
blackbox: true
},
services: {
type: Object,
optional: true,
blackbox: true
},
roles: {
type: Array,
optional: true
},
'roles.$': {
type: Object,
optional: true,
blackbox: true
},
// In order to avoid an 'Exception in setInterval callback' from Meteor
heartbeat: {
type: Date,
optional: true
}
})
You'll probably need to describe
username: {
type: String
},
emails: {
type: Array,
optional: true
},
at least, probably with other fields like profile
Sounds like what you are really looking for is https://docs.meteor.com/api/accounts-multi.html#AccountsServer-onCreateUser, which is the callback function you should use to add more fields to the user document when it is created. You don't really need to attach a schema for that, and from your comment the point of the schema was just to extend the user object somehow. If I understood that correctly, then onCreateUser is definitely the way to go.

Meteor password validation

I'm struggling to figure out how to make password validation with my user Schema, that's how I've being doing so far:
This is the schema:
Schema = {};
Schema.UserProfile = new SimpleSchema({
//LOTS OF FIELDS WORKING FINE
});
Schema.User = new SimpleSchema({
username: {
type: String,
optional: true
},
emails: {
type: Array,
},
"emails.$": {
type: Object
},
"emails.$.address": {
type: String,
regEx: SimpleSchema.RegEx.Email
},
"emails.$.verified": {
type: Boolean
},
createdAt: {
type: Date
},
profile: {
type: Schema.UserProfile,
label: "Perfil",
optional: false
},
services: {
type: Object,
blackbox: true
},
"services.$": {
type: Object,
blackbox: true
},
"services.$.password": { // IS IT RIGHT?
type: String,
label: "Senha",
min: 8
},
roles: {
type: String,
optional: true
}
});
Meteor.users.attachSchema(Schema.User);
And this is how I'm saving:
let company = {};
company = {
email: $('#email').val(),
password: $('#password').val(),
roles: 'company',
profile: companyProfile
}
Meteor.call('saveUser', company, function(error, result) {
if ( error ) {
console.log(error);
}
}
Meteor.methods({
saveUser: function(data) {
return Accounts.createUser(data);
}
});
I'm still a beginner, so I'm probably messing something up here. When I try to create the user, if there is an issue with any of the fields, the validation throws an error as expected. However no error is thrown in case I miss the password, any ideas of what I'm doing wrong here?
------------------------------- UPDATE ----------------------------------
Thanks #aedm for your answer. I really wish I could have something like this to verify the password and password confirmation:
password: {
type: String,
label: "Senha",
min: 8
},
password_confirmation: {
type: String,
label: "Confirmação de Senha",
min: 8,
custom: function () {
if (this.value !== this.field('password').value) {
return "passwordMismatch";
}
}
},
I guess it's not possible then, is it?
Meteor only stores a bcrypt hash for the password, it's always longer than 8 characters.
Instead, your saveUser method should throw an error when the password criteria isn't met.
Meteor.methods({
saveUser: function(data) {
if (data.password.length < 8) throw new Meteor.Error("Password too short");
return Accounts.createUser(data);
}
});
I'd try to avoid defining a schema for users, Meteor handles it pretty well without one, and it's not trivial how to do it properly.

divide Meteor.users into different schemas

I want to have different types of users for my web application. They would have all the methods of normal users, but different Schemas, specifically for settings and profile. Eg:
var UserBase = {
emails: {
type: [Object],
optional: true
},
// ... etc not important
}
AdminSchema = new SimpleSchema(_.extend(UserBase, {
profile: {
type: AdminProfileSchema
},
settings: {
type: AdminSettingsSchema
}
}));
UserSchema = new SimpleSchema(_.extend(UserBase, { // yada yada });
// more or less what I want to do:
Meteor.users.attachSchema(AdminSchema, { role: "admin" });
Meteor.users.attachSchema(UserSchema, { role: "user"});
Is it possible to attach different schemas to Meteor.users, assuming no collisions?
I would have the two schemas (user, admin) as sub-objects of the main user schema, equalling null if they aren't set, like this:
var UserSchema = {
emails: {
type: [Object],
optional: true
},
// ... etc not important
admin: {
type: AdminSchema,
optional: true
},
user: {
type: UserSchema,
optional: true
}
}

update working in Robomongo and not from Meteor

This works and insert {name: 'ok', color: '#ff0000'} to the categories when using Robomongo
db.requirements.update({_id: 'kJBZp2gA8TgNX3z2j'}, {$addToSet: {categories: {name: 'ok', color: '#ff0000'}}})
It does not from Meteor.
It inserts an empty object {} into categories array
EDIT
After SimpleSchema.debug = true; I have this log:
SimpleSchema.clean: filtered out value that would have affected key
"categories.$._id", which is not allowed by the schema
same for name and color thus inserting an empty object {}
The schema is:
categories: {
type: [{
_id: {
type: String
},
name: {
type: String
},
color: {
type: String
}
}],
optional: true
}
What would be the correct schema then ?
I don't grasp all the differences, but here is the new schema that now works. Thanks Matt K for the debug option pointer.
'categories.$._id': {
type: String,
optional: true
},
'categories.$.name': {
type: String,
optional: true
},
'categories.$.color': {
type: String,
optional: true
},

Invalid schema element named "JobeetCategories" at path "JobeetAffiliate"

I have followd this tutorialJoobeet 1.4 Day 3
<code> JobeetCategory:
actAs: { Timestampable: ~ }
columns:
name: { type: string(255), notnull: true, unique: true }
JobeetJob:
actAs: { Timestampable: ~ }
columns:
category_id: { type: integer, notnull: true }
type: { type: string(255) }
company: { type: string(255), notnull: true }
logo: { type: string(255) }
url: { type: string(255) }
position: { type: string(255), notnull: true }
location: { type: string(255), notnull: true }
description: { type: string(4000), notnull: true }
how_to_apply: { type: string(4000), notnull: true }
token: { type: string(255), notnull: true, unique: true }
is_public: { type: boolean, notnull: true, default: 1 }
is_activated: { type: boolean, notnull: true, default: 0 }
email: { type: string(255), notnull: true }
expires_at: { type: timestamp, notnull: true }
relations:
JobeetCategory: { onDelete: CASCADE, local: category_id, foreign: id, foreignAlias: JobeetJobs }
JobeetAffiliate:
actAs: { Timestampable: ~ }
columns:
url: { type: string(255), notnull: true }
email: { type: string(255), notnull: true, unique: true }
token: { type: string(255), notnull: true }
is_active: { type: boolean, notnull: true, default: 0 }
relations:
JobeetCategories:
class: JobeetCategory
refClass: JobeetCategoryAffiliate
local: affiliate_id
foreign: category_id
foreignAlias: JobeetAffiliates
JobeetCategoryAffiliate:
columns:
category_id: { type: integer, primary: true }
affiliate_id: { type: integer, primary: true }
relations:
JobeetCategory: { onDelete: CASCADE, local: category_id, foreign: id }
JobeetAffiliate: { onDelete: CASCADE, local: affiliate_id, foreign: id } </code>
Your code is working in me.
1. Check schema.yml for syntax error.
2.
2.1 Back Up your project.
2.2 (I think this is help you). Go to the lib/model/doctrine/base - and delete all files.
Make :
$ php symfony doctrine:build --all --and-load --no-confirmation
UPD : Delete all files also in : lib/form/doctrine/base, lib/filter/doctrine/base

Resources